summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/resources')
-rw-r--r--chromium/chrome/browser/resources/BUILD.gn42
-rw-r--r--chromium/chrome/browser/resources/app_management/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/app_management/OWNERS5
-rw-r--r--chromium/chrome/browser/resources/app_management/actions.html2
-rw-r--r--chromium/chrome/browser/resources/app_management/actions.js100
-rw-r--r--chromium/chrome/browser/resources/app_management/api_listener.html5
-rw-r--r--chromium/chrome/browser/resources/app_management/api_listener.js64
-rw-r--r--chromium/chrome/browser/resources/app_management/app_item.html41
-rw-r--r--chromium/chrome/browser/resources/app_management/app_item.js38
-rw-r--r--chromium/chrome/browser/resources/app_management/arc_permission_view.html82
-rw-r--r--chromium/chrome/browser/resources/app_management/arc_permission_view.js70
-rw-r--r--chromium/chrome/browser/resources/app_management/browser_proxy.html13
-rw-r--r--chromium/chrome/browser/resources/app_management/browser_proxy.js125
-rw-r--r--chromium/chrome/browser/resources/app_management/chrome_app_permission_view.html92
-rw-r--r--chromium/chrome/browser/resources/app_management/chrome_app_permission_view.js79
-rw-r--r--chromium/chrome/browser/resources/app_management/constants.html1
-rw-r--r--chromium/chrome/browser/resources/app_management/constants.js51
-rw-r--r--chromium/chrome/browser/resources/app_management/dom_switch.html8
-rw-r--r--chromium/chrome/browser/resources/app_management/dom_switch.js128
-rw-r--r--chromium/chrome/browser/resources/app_management/expandable_app_list.html1
-rw-r--r--chromium/chrome/browser/resources/app_management/fake_page_handler.js227
-rw-r--r--chromium/chrome/browser/resources/app_management/icons.html17
-rw-r--r--chromium/chrome/browser/resources/app_management/main_view.html73
-rw-r--r--chromium/chrome/browser/resources/app_management/main_view.js122
-rw-r--r--chromium/chrome/browser/resources/app_management/metadata_view.html72
-rw-r--r--chromium/chrome/browser/resources/app_management/metadata_view.js92
-rw-r--r--chromium/chrome/browser/resources/app_management/notifications_view.html53
-rw-r--r--chromium/chrome/browser/resources/app_management/notifications_view.js166
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_item.html42
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_item.js84
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_toggle.html37
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_toggle.js142
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_view_header.html62
-rw-r--r--chromium/chrome/browser/resources/app_management/permission_view_header.js111
-rw-r--r--chromium/chrome/browser/resources/app_management/pin_to_shelf_item.html19
-rw-r--r--chromium/chrome/browser/resources/app_management/pin_to_shelf_item.js95
-rw-r--r--chromium/chrome/browser/resources/app_management/pwa_permission_view.html65
-rw-r--r--chromium/chrome/browser/resources/app_management/pwa_permission_view.js65
-rw-r--r--chromium/chrome/browser/resources/app_management/reducers.html2
-rw-r--r--chromium/chrome/browser/resources/app_management/reducers.js314
-rw-r--r--chromium/chrome/browser/resources/app_management/router.html17
-rw-r--r--chromium/chrome/browser/resources/app_management/router.js162
-rw-r--r--chromium/chrome/browser/resources/app_management/search_view.html43
-rw-r--r--chromium/chrome/browser/resources/app_management/search_view.js40
-rw-r--r--chromium/chrome/browser/resources/app_management/shared_style.html113
-rw-r--r--chromium/chrome/browser/resources/app_management/shared_vars.html27
-rw-r--r--chromium/chrome/browser/resources/app_management/store.html6
-rw-r--r--chromium/chrome/browser/resources/app_management/store.js24
-rw-r--r--chromium/chrome/browser/resources/app_management/store_client.html5
-rw-r--r--chromium/chrome/browser/resources/app_management/store_client.js48
-rw-r--r--chromium/chrome/browser/resources/app_management/toggle_row.html55
-rw-r--r--chromium/chrome/browser/resources/app_management/toggle_row.js34
-rw-r--r--chromium/chrome/browser/resources/app_management/types.js63
-rw-r--r--chromium/chrome/browser/resources/app_management/util.html2
-rw-r--r--chromium/chrome/browser/resources/app_management/util.js261
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn23
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js26
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js2
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/device_broker.js12
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/device_details_page.js26
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/resources.grd115
-rw-r--r--chromium/chrome/browser/resources/bookmarks/command_manager.js37
-rw-r--r--chromium/chrome/browser/resources/bookmarks/folder_node.html2
-rw-r--r--chromium/chrome/browser/resources/bookmarks/folder_node.js5
-rw-r--r--chromium/chrome/browser/resources/bookmarks/item.html3
-rw-r--r--chromium/chrome/browser/resources/bookmarks/item.js37
-rw-r--r--chromium/chrome/browser/resources/bookmarks/shared_style.html3
-rw-r--r--chromium/chrome/browser/resources/cast/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/cast/cast.css18
-rw-r--r--chromium/chrome/browser/resources/cast/cast.html3
-rw-r--r--chromium/chrome/browser/resources/cast/cast.js36
-rw-r--r--chromium/chrome/browser/resources/cast/cast_favicon.icobin32988 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/chromeos/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/BUILD.gn19
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd15
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json16
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn16
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn7
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/models/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn15
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn23
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd12
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd29
-rw-r--r--chromium/chrome/browser/resources/chromeos/genius_app/manifest.json3
-rw-r--r--chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn33
-rw-r--r--chromium/chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd12
-rw-r--r--chromium/chrome/browser/resources/component_extension_resources.grd3
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/cryptotokenbackground.js3
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/enroller.js4
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/manifest.json3
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/signer.js3
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/webrequest.js52
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/webrequestsender.js4
-rw-r--r--chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css45
-rw-r--r--chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.grdp6
-rw-r--r--chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.html22
-rw-r--r--chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.js51
-rw-r--r--chromium/chrome/browser/resources/device_log_ui/device_log_ui.js6
-rw-r--r--chromium/chrome/browser/resources/discards/discards_tab.js3
-rw-r--r--chromium/chrome/browser/resources/downloads/item.js8
-rw-r--r--chromium/chrome/browser/resources/extensions/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/extensions/item.html1
-rw-r--r--chromium/chrome/browser/resources/extensions/item.js30
-rw-r--r--chromium/chrome/browser/resources/extensions/manager.html2
-rw-r--r--chromium/chrome/browser/resources/extensions/toolbar.html13
-rw-r--r--chromium/chrome/browser/resources/extensions/toolbar.js39
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/authenticator.js29
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js11
-rw-r--r--chromium/chrome/browser/resources/hats/hats.html82
-rw-r--r--chromium/chrome/browser/resources/help_app/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/history/constants.js4
-rw-r--r--chromium/chrome/browser/resources/history/externs.js2
-rw-r--r--chromium/chrome/browser/resources/history/history_item.js19
-rw-r--r--chromium/chrome/browser/resources/history/synced_device_card.js4
-rw-r--r--chromium/chrome/browser/resources/inline_login/inline_login.css47
-rw-r--r--chromium/chrome/browser/resources/inline_login/inline_login.html12
-rw-r--r--chromium/chrome/browser/resources/inline_login/inline_login.js25
-rw-r--r--chromium/chrome/browser/resources/local_discovery/local_discovery.js3
-rw-r--r--chromium/chrome/browser/resources/local_ntp/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/local_ntp/customize.css14
-rw-r--r--chromium/chrome/browser/resources/local_ntp/customize.js117
-rw-r--r--chromium/chrome/browser/resources/local_ntp/externs.js41
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.css39
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.html13
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.js1549
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.css4
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.html1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.js9
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_title.html1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_util.js8
-rw-r--r--chromium/chrome/browser/resources/local_state/BUILD.gn4
-rw-r--r--chromium/chrome/browser/resources/local_state/local_state.html5
-rw-r--r--chromium/chrome/browser/resources/local_state/local_state.js4
-rw-r--r--chromium/chrome/browser/resources/management/management_browser_proxy.js26
-rw-r--r--chromium/chrome/browser/resources/management/management_ui.html48
-rw-r--r--chromium/chrome/browser/resources/management/management_ui.js24
-rw-r--r--chromium/chrome/browser/resources/media/media_engagement.html24
-rw-r--r--chromium/chrome/browser/resources/media/media_engagement.js21
-rw-r--r--chromium/chrome/browser/resources/media_router/extension/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/ntp4/dot_list.js2
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_tab.html2
-rw-r--r--chromium/chrome/browser/resources/ntp4/page_list_view.js10
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox.html2
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox.js29
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox_output.js6
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css1
-rw-r--r--chromium/chrome/browser/resources/omnibox/output_results_group.css3
-rw-r--r--chromium/chrome/browser/resources/pdf/BUILD.gn23
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html10
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js63
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html12
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js5
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js4
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn20
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html13
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js135
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn15
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js86
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn25
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html6
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js86
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js20
-rw-r--r--chromium/chrome/browser/resources/pdf/index.html3
-rw-r--r--chromium/chrome/browser/resources/pdf/navigator.js252
-rw-r--r--chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js8
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf_viewer.js91
-rw-r--r--chromium/chrome/browser/resources/pdf/viewport.js623
-rw-r--r--chromium/chrome/browser/resources/pdf/viewport_interface.js136
-rw-r--r--chromium/chrome/browser/resources/pdf/zoom_manager.js79
-rw-r--r--chromium/chrome/browser/resources/policy/policy.css9
-rw-r--r--chromium/chrome/browser/resources/policy/policy.html18
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination.js525
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination_store.js82
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/invitation_store.js36
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/margins.js79
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/measurement_system.js75
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/model.js218
-rw-r--r--chromium/chrome/browser/resources/print_preview/native_layer.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/polymer3/demo.js135
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/app.js2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_settings.js915
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/highlight_utils.js17
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margin_control.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margin_control.js26
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js982
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js68
-rw-r--r--chromium/chrome/browser/resources/protobufs/OWNERS4
-rw-r--r--chromium/chrome/browser/resources/reset_password/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/reset_password/reset_password.js8
-rw-r--r--chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py56
-rw-r--r--chromium/chrome/browser/resources/safety_tips/README.md1
-rwxr-xr-xchromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py10
-rwxr-xr-xchromium/chrome/browser/resources/safety_tips/push_proto.py89
-rw-r--r--chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb23
-rw-r--r--chromium/chrome/browser/resources/set_as_default_browser.css159
-rw-r--r--chromium/chrome/browser/resources/set_as_default_browser.html39
-rw-r--r--chromium/chrome/browser/resources/set_as_default_browser.js16
-rw-r--r--chromium/chrome/browser/resources/settings/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/OWNERS3
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html75
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js20
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.html163
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.js119
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html5
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js27
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.html19
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.js51
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/about_page.html20
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/about_page.js16
-rw-r--r--chromium/chrome/browser/resources/settings/app_management_page/app_management_page.html14
-rw-r--r--chromium/chrome/browser/resources/settings/app_management_page/app_management_page.js19
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/BUILD.gn12
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js34
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html4
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js31
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.js48
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn4
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html27
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js130
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.html55
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.js100
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html1
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js14
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html2
-rw-r--r--chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js2
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn (renamed from chromium/chrome/browser/resources/settings/app_management_page/BUILD.gn)9
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn230
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_reset_page/BUILD.gn7
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_settings_menu/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn18
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn10
-rw-r--r--chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html9
-rw-r--r--chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js4
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js25
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.html13
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.js21
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_page.html2
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_page.js23
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.html14
-rw-r--r--chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.js11
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html6
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js11
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.html2
-rw-r--r--chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.js20
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/device_page.html2
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js28
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/display_overscan_dialog.html4
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/pointers.html16
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/pointers.js11
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage.html2
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage.js4
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage_external.html21
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage_external.js46
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage_external_entry.html25
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage_external_entry.js72
-rw-r--r--chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js2
-rw-r--r--chromium/chrome/browser/resources/settings/icons.html78
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/BUILD.gn16
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html169
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js1159
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html12
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js49
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.html16
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.js259
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page_browser_proxy.js43
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_subpage.html32
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js259
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html21
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js28
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary.html1
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary.js23
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html11
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js30
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html20
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js72
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/languages_page.js18
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.html2
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js6
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.js7
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js15
-rw-r--r--chromium/chrome/browser/resources/settings/os_settings_resources.grd195
-rw-r--r--chromium/chrome/browser/resources/settings/page_visibility.js10
-rw-r--r--chromium/chrome/browser/resources/settings/parental_controls_page/parental_controls_page.html12
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/account_manager.html15
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/account_manager.js3
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.js10
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/fingerprint_list.js7
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.html6
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.js23
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.html31
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.js24
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/lock_screen.html6
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/lock_screen.js13
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/people_page.html90
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/people_page.js158
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html33
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js25
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js15
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_controls.html16
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_page.html24
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_page.js14
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/OWNERS2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html6
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js13
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html91
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js36
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html12
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js28
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printer_types.js2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers.html117
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers.js96
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html12
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html10
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js40
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js44
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn12
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html51
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js18
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html118
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js273
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js138
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html1
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js2
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html1
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js8
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.html15
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js27
-rw-r--r--chromium/chrome/browser/resources/settings/route.js364
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html2
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html2
-rw-r--r--chromium/chrome/browser/resources/settings/search_settings.js2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_main/settings_main.html1
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html23
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html10
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_subpage.js2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_resources.grd34
-rw-r--r--chromium/chrome/browser/resources/settings/settings_shared_css.html7
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html3
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js6
-rw-r--r--chromium/chrome/browser/resources/settings/site_favicon.html6
-rw-r--r--chromium/chrome/browser/resources/settings/site_favicon.js22
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js1
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html6
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js36
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/constants.js1
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/cookie_info.js4
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/local_data_browser_proxy.js13
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_data.html25
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_data.js41
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js1
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.html7
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.js9
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js9
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list.html2
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list.js24
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js5
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html29
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js24
-rw-r--r--chromium/chrome/browser/resources/snippets_internals/snippets_internals.js38
-rw-r--r--chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp4
-rw-r--r--chromium/chrome/browser/resources/tab_strip/BUILD.gn61
-rw-r--r--chromium/chrome/browser/resources/tab_strip/OWNERS2
-rw-r--r--chromium/chrome/browser/resources/tab_strip/custom_element.js17
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab.html109
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab.js153
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.html51
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.js249
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip.html53
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd44
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js68
-rw-r--r--chromium/chrome/browser/resources/tab_strip/types.js32
-rw-r--r--chromium/chrome/browser/resources/usb_internals/BUILD.gn11
-rw-r--r--chromium/chrome/browser/resources/usb_internals/descriptor_panel.js285
-rw-r--r--chromium/chrome/browser/resources/usb_internals/devices_page.js87
-rw-r--r--chromium/chrome/browser/resources/usb_internals/usb_internals.js12
-rw-r--r--chromium/chrome/browser/resources/web_footer_experiment/index.html10
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html24
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_resources.grd (renamed from chromium/chrome/browser/resources/welcome/onboarding_welcome_resources.grd)114
393 files changed, 10226 insertions, 10028 deletions
diff --git a/chromium/chrome/browser/resources/BUILD.gn b/chromium/chrome/browser/resources/BUILD.gn
index 5f26c76da3c..d1b6a8b7b45 100644
--- a/chromium/chrome/browser/resources/BUILD.gn
+++ b/chromium/chrome/browser/resources/BUILD.gn
@@ -12,6 +12,7 @@ if (closure_compile) {
deps = [
"engagement:closure_compile",
"interventions_internals:closure_compile",
+ "reset_password:closure_compile",
]
if (is_linux || is_win || is_mac) {
deps += [
@@ -30,6 +31,7 @@ if (closure_compile) {
"quota_internals:closure_compile",
"settings:closure_compile",
"signin/sync_confirmation:closure_compile",
+ "usb_internals:closure_compile",
"user_manager:closure_compile",
"welcome:closure_compile",
]
@@ -40,6 +42,9 @@ if (closure_compile) {
if (enable_extensions) {
deps += [ "extensions:closure_compile" ]
}
+ if (enable_webui_tab_strip) {
+ deps += [ "tab_strip:closure_compile" ]
+ }
if (is_android) {
deps += [
"explore_sites_internals:closure_compile",
@@ -49,9 +54,6 @@ if (closure_compile) {
"webapks:closure_compile",
]
}
- if (!is_android) {
- deps += [ "app_management:closure_compile" ]
- }
if (is_win || is_mac || is_desktop_linux) {
deps += [ "browser_switch:closure_compile" ]
}
@@ -219,15 +221,15 @@ if (is_chromeos) {
}
if (!is_android && !is_chromeos) {
- grit("onboarding_welcome_resources") {
- source = "welcome/onboarding_welcome_resources.grd"
+ grit("welcome_resources") {
+ source = "welcome/welcome_resources.grd"
defines = chrome_grit_defines
outputs = [
- "grit/onboarding_welcome_resources.h",
- "grit/onboarding_welcome_resources_map.cc",
- "grit/onboarding_welcome_resources_map.h",
- "onboarding_welcome_resources.pak",
+ "grit/welcome_resources.h",
+ "grit/welcome_resources_map.cc",
+ "grit/welcome_resources_map.h",
+ "welcome_resources.pak",
]
output_dir = "$root_gen_dir/chrome"
}
@@ -303,3 +305,25 @@ if (enable_print_preview) {
output_dir = "$root_gen_dir/chrome"
}
}
+
+if (enable_webui_tab_strip) {
+ grit("tab_strip_resources") {
+ source = "tab_strip/tab_strip_resources.grd"
+ defines = chrome_grit_defines
+ deps = [
+ "tab_strip:tab_strip_modules",
+ ]
+ source_is_generated = true
+ outputs = [
+ "grit/tab_strip_resources.h",
+ "grit/tab_strip_resources_map.cc",
+ "grit/tab_strip_resources_map.h",
+ "tab_strip_resources.pak",
+ ]
+ output_dir = "$root_gen_dir/chrome"
+ grit_flags = [
+ "-E",
+ "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+ ]
+ }
+}
diff --git a/chromium/chrome/browser/resources/app_management/BUILD.gn b/chromium/chrome/browser/resources/app_management/BUILD.gn
index d52e422fd0e..05147eec84f 100644
--- a/chromium/chrome/browser/resources/app_management/BUILD.gn
+++ b/chromium/chrome/browser/resources/app_management/BUILD.gn
@@ -256,6 +256,7 @@ if (!is_android) {
js_library("toggle_row") {
deps = [
":types",
+ "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle",
]
}
diff --git a/chromium/chrome/browser/resources/app_management/OWNERS b/chromium/chrome/browser/resources/app_management/OWNERS
index 54640cb9d84..94b2e07d850 100644
--- a/chromium/chrome/browser/resources/app_management/OWNERS
+++ b/chromium/chrome/browser/resources/app_management/OWNERS
@@ -1,5 +1,4 @@
-calamity@chromium.org
dominickn@chromium.org
-ericwilligers@chromium.org
+jshikaram@chromium.org
-# COMPONENT: Platform>Apps>Foundation \ No newline at end of file
+# COMPONENT: Platform>Apps>Foundation
diff --git a/chromium/chrome/browser/resources/app_management/actions.html b/chromium/chrome/browser/resources/app_management/actions.html
deleted file mode 100644
index ad1570cd227..00000000000
--- a/chromium/chrome/browser/resources/app_management/actions.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="actions.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/actions.js b/chromium/chrome/browser/resources/app_management/actions.js
deleted file mode 100644
index 24cdddee569..00000000000
--- a/chromium/chrome/browser/resources/app_management/actions.js
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 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 Module for functions which produce action objects. These are
- * listed in one place to document available actions and their parameters.
- */
-
-cr.define('app_management.actions', function() {
- /**
- * @param {App} app
- */
- function addApp(app) {
- return {
- name: 'add-app',
- app: app,
- };
- }
-
- /**
- * @param {App} app
- */
- function changeApp(app) {
- return {
- name: 'change-app',
- app: app,
- };
- }
-
- /**
- * @param {string} id
- */
- function removeApp(id) {
- return {
- name: 'remove-app',
- id: id,
- };
- }
-
- /**
- * @param {PageType} pageType
- * @param {string=} id
- */
- function changePage(pageType, id) {
- if (pageType === PageType.DETAIL && !id) {
- console.warn(
- 'Tried to load app detail page without providing an app id.');
- }
-
- return {
- name: 'change-page',
- pageType: pageType,
- id: id,
- };
- }
-
- /** @return {!cr.ui.Action} */
- function clearSearch() {
- return {
- name: 'clear-search',
- };
- }
-
- /**
- * @param {string} term
- * @return {!cr.ui.Action}
- */
- function setSearchTerm(term) {
- if (!term) {
- return clearSearch();
- }
- return {
- name: 'start-search',
- term: term,
- };
- }
-
- /**
- * @param {boolean} isSupported
- * @return {!cr.ui.Action}
- */
- function updateArcSupported(isSupported) {
- return {
- name: 'update-arc-supported',
- value: isSupported,
- };
- }
-
-
- return {
- addApp: addApp,
- changeApp: changeApp,
- removeApp: removeApp,
- changePage: changePage,
- clearSearch: clearSearch,
- setSearchTerm: setSearchTerm,
- updateArcSupported: updateArcSupported,
- };
-});
diff --git a/chromium/chrome/browser/resources/app_management/api_listener.html b/chromium/chrome/browser/resources/app_management/api_listener.html
deleted file mode 100644
index 751d6c4e553..00000000000
--- a/chromium/chrome/browser/resources/app_management/api_listener.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="actions.html">
-<link rel="import" href="store.html">
-<link rel="import" href="util.html">
-<script src="api_listener.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/api_listener.js b/chromium/chrome/browser/resources/app_management/api_listener.js
deleted file mode 100644
index 617e94b83c6..00000000000
--- a/chromium/chrome/browser/resources/app_management/api_listener.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 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('app_management.apiListener', function() {
- let initialized = false;
-
- async function init() {
- assert(!initialized);
-
- const {apps: initialApps} =
- await app_management.BrowserProxy.getInstance().handler.getApps();
- const initialState = app_management.util.createInitialState(initialApps);
- app_management.Store.getInstance().init(initialState);
-
- const callbackRouter =
- app_management.BrowserProxy.getInstance().callbackRouter;
-
- callbackRouter.onAppAdded.addListener(onAppAdded);
- callbackRouter.onAppChanged.addListener(onAppChanged);
- callbackRouter.onAppRemoved.addListener(onAppRemoved);
- callbackRouter.onArcSupportChanged.addListener(onArcSupportChanged);
-
- initialized = true;
- }
-
- /**
- * @param {cr.ui.Action} action
- */
- function dispatch(action) {
- app_management.Store.getInstance().dispatch(action);
- }
-
- /**
- * @param {App} app
- */
- function onAppAdded(app) {
- dispatch(app_management.actions.addApp(app));
- }
-
- /**
- * @param {App} app
- */
- function onAppChanged(app) {
- dispatch(app_management.actions.changeApp(app));
- }
-
- /**
- * @param {string} appId
- */
- function onAppRemoved(appId) {
- dispatch(app_management.actions.removeApp(appId));
- }
-
- /**
- * @param {boolean} isSupported
- */
- function onArcSupportChanged(isSupported) {
- dispatch(app_management.actions.updateArcSupported(isSupported));
- }
-
- init();
-
- return {};
-});
diff --git a/chromium/chrome/browser/resources/app_management/app_item.html b/chromium/chrome/browser/resources/app_management/app_item.html
deleted file mode 100644
index b7a7576080d..00000000000
--- a/chromium/chrome/browser/resources/app_management/app_item.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="actions.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="shared_vars.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
-
-<dom-module id="app-management-app-item">
- <template>
- <style include="app-management-shared-css cr-icons">
- :host {
- align-items: center;
- border-top: var(--card-separator);
- color: var(--primary-text-color);
- cursor: pointer;
- display: flex;
- flex-direction: row;
- font-weight: 400;
- height: 64px;
- }
-
- #app-title {
- flex: 1;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- #app-icon {
- height: 32px;
- margin-inline-end: 20px;
- margin-inline-start: 24px;
- width: 32px;
- }
- </style>
- <img id="app-icon" src="[[iconUrlFromId_(app)]]">
- <div id="app-title">[[app.title]]</div>
- <slot name="right-content"></slot>
- </template>
- <script src="app_item.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/app_item.js b/chromium/chrome/browser/resources/app_management/app_item.js
deleted file mode 100644
index aaceae573f1..00000000000
--- a/chromium/chrome/browser/resources/app_management/app_item.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-app-item',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /** @type {App} */
- app: {
- type: Object,
- },
- },
-
- listeners: {
- 'click': 'onClick_',
- },
-
- /**
- * @private
- */
- onClick_: function() {
- this.dispatch(
- app_management.actions.changePage(PageType.DETAIL, this.app.id));
- },
-
- /**
- * @param {App} app
- * @return {string}
- * @private
- */
- iconUrlFromId_: function(app) {
- return app_management.util.getAppIcon(app);
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/arc_permission_view.html b/chromium/chrome/browser/resources/app_management/arc_permission_view.html
deleted file mode 100644
index 1ffb3a6b0cb..00000000000
--- a/chromium/chrome/browser/resources/app_management/arc_permission_view.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="browser_proxy.html">
-<link rel="import" href="icons.html">
-<link rel="import" href="metadata_view.html">
-<link rel="import" href="permission_item.html">
-<link rel="import" href="permission_view_header.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="pin_to_shelf_item.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-
-<dom-module id="app-management-arc-permission-view">
- <template>
- <style include="app-management-shared-css">
- </style>
-
- <app-management-permission-view-header>
- </app-management-permission-view-header>
-
- <div class="permission-list card-container">
- <app-management-pin-to-shelf-item
- id="pin-to-shelf-setting"
- class="permission-card-row separated-row header-text"
- app_="[[app_]]">
- </app-management-pin-to-shelf-item>
- <app-management-permission-item id="notifications-card"
- class="permission-card-row separated-row header-text"
- permission-label="$i18n{notifications}" permission-type="NOTIFICATIONS"
- hidden$="[[!isArcSupported_]]">
- </app-management-permission-item>
- <div id="permissions-card"
- class="permission-card-row"
- hidden$="[[!isArcSupported_]]">
- <div class="subpermission-list">
- <div id="subpermission-expand-row"
- class="subpermission-row separated-row"
- hidden$="[[!isArcSupported_]]">
- <div class="header-text">$i18n{permissions}</div>
- </div>
- <app-management-permission-item class="subpermission-row"
- icon="cr:location-on"
- permission-label="$i18n{location}"
- permission-type="LOCATION">
- </app-management-permission-item>
- <app-management-permission-item class="subpermission-row"
- icon="cr:videocam"
- permission-label="$i18n{camera}"
- permission-type="CAMERA">
- </app-management-permission-item>
- <app-management-permission-item class="subpermission-row"
- icon="cr:mic"
- permission-label="$i18n{microphone}"
- permission-type="MICROPHONE">
- </app-management-permission-item>
- <app-management-permission-item class="subpermission-row"
- icon="app-management:contacts"
- permission-label="$i18n{contacts}"
- permission-type="CONTACTS">
- </app-management-permission-item>
- <app-management-permission-item class="subpermission-row"
- icon="app-management:storage"
- permission-label="$i18n{storage}"
- permission-type="STORAGE">
- </app-management-permission-item>
- </div>
- </div>
- <div id="more-settings"
- class="permission-card-row separated-row header-text clickable"
- on-click="onClickNativeSettingsButton_">
- <div class="header-text">$i18n{moreSettings}</div>
- <div class="permission-row-controls">
- <cr-icon-button class="native-settings-icon icon-external"
- tabindex="0">
- </cr-icon-button>
- </div>
- </div>
- </div>
- </template>
- <script src="arc_permission_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/arc_permission_view.js b/chromium/chrome/browser/resources/app_management/arc_permission_view.js
deleted file mode 100644
index 0242a758b5c..00000000000
--- a/chromium/chrome/browser/resources/app_management/arc_permission_view.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-arc-permission-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * @private {App}
- */
- app_: Object,
-
- /**
- * @private {boolean}
- */
- listExpanded_: {
- type: Boolean,
- value: false,
- },
-
- /**
- * @private {boolean}
- */
- isArcSupported_: {
- type: Boolean,
- }
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.watch('isArcSupported_', state => state.arcSupported);
- this.updateFromStore();
-
- this.listExpanded_ = false;
- },
-
- onClickNativeSettingsButton_: function() {
- app_management.BrowserProxy.getInstance().handler.openNativeSettings(
- this.app_.id);
- },
-
- /**
- * @private
- */
- toggleListExpanded_: function() {
- this.listExpanded_ = !this.listExpanded_;
- },
-
- /**
- * @param {App} app
- * @return {string}
- * @private
- */
- iconUrlFromId_: function(app) {
- return app_management.util.getAppIcon(app);
- },
-
- /**
- * @param {boolean} listExpanded
- * @return {string}
- * @private
- */
- getCollapsedIcon_: function(listExpanded) {
- return listExpanded ? 'cr:expand-less' : 'cr:expand-more';
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/browser_proxy.html b/chromium/chrome/browser/resources/app_management/browser_proxy.html
deleted file mode 100644
index e66afd27a8a..00000000000
--- a/chromium/chrome/browser/resources/app_management/browser_proxy.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
-<link rel="import" href="chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom.html">
-<link rel="import" href="chrome://resources/mojo/mojo/public/mojom/base/time.mojom.html">
-
-<script src="image_info.mojom-lite.js"></script>
-<script src="bitmap.mojom-lite.js"></script>
-<script src="image.mojom-lite.js"></script>
-<script src="types.mojom-lite.js"></script>
-<script src="app_management.mojom-lite.js"></script>
-
-<script src="browser_proxy.js"></script>
-<script src="fake_page_handler.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/browser_proxy.js b/chromium/chrome/browser/resources/app_management/browser_proxy.js
deleted file mode 100644
index f824557fc9c..00000000000
--- a/chromium/chrome/browser/resources/app_management/browser_proxy.js
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2018 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('app_management', function() {
- class BrowserProxy {
- constructor() {
- /** @type {appManagement.mojom.PageCallbackRouter} */
- this.callbackRouter = new appManagement.mojom.PageCallbackRouter();
-
- /** @type {appManagement.mojom.PageHandlerRemote} */
- this.handler = null;
-
- const urlParams = new URLSearchParams(window.location.search);
- const arcSupported = urlParams.get('arcSupported');
- const useFake = urlParams.get('fakeBackend');
-
- if (useFake) {
- if (arcSupported) {
- loadTimeData.overrideValues({
- 'isSupportedArcVersion': arcSupported.toLowerCase() === 'true',
- });
- } else {
- loadTimeData.overrideValues({
- 'isSupportedArcVersion': true,
- });
- }
-
- this.fakeHandler = new app_management.FakePageHandler(
- this.callbackRouter.$.bindNewPipeAndPassRemote());
- this.handler = this.fakeHandler.getRemote();
-
- const permissionOptions = {};
- permissionOptions[PwaPermissionType.CONTENT_SETTINGS_TYPE_GEOLOCATION] =
- {
- permissionValue: TriState.kAllow,
- isManaged: true,
- };
- permissionOptions[PwaPermissionType
- .CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = {
- permissionValue: TriState.kBlock,
- isManaged: true
- };
-
- const /** @type {!Array<App>}*/ appList = [
- app_management.FakePageHandler.createApp(
- 'blpcfgokakmgnkcojhhkbfblekacnbeo',
- {
- title: 'Built in app, not implemented',
- type: AppType.kBuiltIn,
- installSource: InstallSource.kSystem,
- },
- ),
- app_management.FakePageHandler.createApp(
- 'aohghmighlieiainnegkcijnfilokake',
- {
- title: 'Arc app',
- type: AppType.kArc,
- installSource: InstallSource.kUser,
- },
- ),
- app_management.FakePageHandler.createApp(
- 'blpcfgokakmgnkcojhhkbfbldkacnbeo',
- {
- title: 'Crostini app, not implemented',
- type: AppType.kCrostini,
- installSource: InstallSource.kUser,
- },
- ),
- app_management.FakePageHandler.createApp(
- 'pjkljhegncpnkkknowihdijeoejaedia',
- {
- title: 'Chrome App',
- type: AppType.kExtension,
- description:
- 'A Chrome App installed from the Chrome Web Store.',
- },
- ),
- app_management.FakePageHandler.createApp(
- 'aapocclcdoekwnckovdopfmtonfmgok',
- {
- title: 'Web App',
- type: AppType.kWeb,
- },
- ),
- app_management.FakePageHandler.createApp(
- 'pjkljhegncpnkkknbcohdijeoejaedia',
- {
- title: 'Chrome App, OEM installed',
- type: AppType.kExtension,
- description: 'A Chrome App installed by an OEM.',
- installSource: InstallSource.kOem,
- },
- ),
- app_management.FakePageHandler.createApp(
- 'aapocclcgogkmnckokdopfmhonfmgok',
- {
- title: 'Web App, policy applied',
- type: AppType.kWeb,
- isPinned: apps.mojom.OptionalBool.kTrue,
- isPolicyPinned: apps.mojom.OptionalBool.kTrue,
- installSource: apps.mojom.InstallSource.kPolicy,
- permissions:
- app_management.FakePageHandler.createWebPermissions(
- permissionOptions),
- },
- ),
- ];
-
- this.fakeHandler.setApps(appList);
-
- } else {
- this.handler = new appManagement.mojom.PageHandlerRemote();
- const factory = appManagement.mojom.PageHandlerFactory.getRemote();
- factory.createPageHandler(
- this.callbackRouter.$.bindNewPipeAndPassRemote(),
- this.handler.$.bindNewPipeAndPassReceiver());
- }
- }
- }
-
- cr.addSingletonGetter(BrowserProxy);
-
- return {BrowserProxy: BrowserProxy};
-});
diff --git a/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.html b/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.html
deleted file mode 100644
index 64b890ff985..00000000000
--- a/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="util.html">
-<link rel="import" href="pin_to_shelf_item.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-
-<dom-module id="app-management-chrome-app-permission-view">
- <template>
- <style include="app-management-shared-css">
- ul {
- list-style: disc inside;
- margin: 0;
- margin-inline-start: 24px;
- padding: 0;
- }
-
- #app-description {
- padding: 24px;
- }
-
- #no-permissions {
- padding-inline-start: 24px;
- }
-
- #pin-to-shelf-setting {
- border-top: var(--card-separator);
- }
-
- </style>
- <app-management-permission-view-header>
- </app-management-permission-view-header>
- <div class="card-container">
- <div id="app-description" class="permission-card-row secondary-text">
- [[app_.description]]
- </div>
- <div class="permission-list">
- <app-management-pin-to-shelf-item
- id="pin-to-shelf-setting"
- class="permission-card-row separated-row header-text"
- app_="[[app_]]">
- </app-management-pin-to-shelf-item>
-
- <div id="permissions-card" class="permission-card-row">
- <div class="subpermission-list">
- <div class="subpermission-row separated-row">
- <div class="header-text">$i18n{thisAppCan}</div>
- </div>
- <template is="dom-if" if="[[!hasPermissions_(messages_)]]">
- <div id="no-permissions">
- $i18n{appNoPermission}
- </div>
- </template>
- <ul>
- <template is="dom-repeat"
- items="[[getPermissionMessages_(messages_)]]" as="message">
- <li>[[message]]</li>
- <ul>
- <template is="dom-repeat"
- items="[[getPermissionSubmessagesByMessage_(index, messages_)]]"
- as="submessage">
- <li>[[submessage]]</li>
- </template>
- </ul>
- </template>
- </ul>
- <!-- TODO(crbug.com/906508): For apps which are hosted apps but not
- bookmark apps, this button will actually open the site settings page
- corresponding to the app, since hosted apps are not listed in
- chrome://extensions.
- This is not a long-term problem since hosted apps are being
- replaced, but in the mean time it might be necessary to change the
- text of the button depending on whether or not it is a hosted
- app. -->
- <!-- TODO:(crbug.com/958269) Change behaviour of "more settings"
- based on the app. -->
- <div id="more-settings"
- class="subpermission-row separated-row clickable"
- on-click="onClickExtensionsSettingsButton_"
- hidden$="[[app_.hideMoreSettings]]">
- <div class="header-text">$i18n{moreSettings}</div>
- <cr-icon-button class="native-settings-icon icon-external"
- tabindex="0">
- </cr-icon-button>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script src="chrome_app_permission_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.js b/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.js
deleted file mode 100644
index f697f55754e..00000000000
--- a/chromium/chrome/browser/resources/app_management/chrome_app_permission_view.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-chrome-app-permission-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * @private {App}
- */
- app_: {
- type: Object,
- observer: 'onAppChanged_',
- },
-
- /**
- * @private {Array<ExtensionAppPermissionMessage>}
- */
- messages_: Object,
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.updateFromStore();
- },
-
- /**
- * @private
- */
- onAppChanged_: async function() {
- const {messages: messages} =
- await app_management.BrowserProxy.getInstance()
- .handler.getExtensionAppPermissionMessages(this.app_.id);
- this.$['app-description'].hidden = this.app_.description.length === 0;
- this.messages_ = messages;
- },
-
- onClickExtensionsSettingsButton_: function() {
- app_management.BrowserProxy.getInstance().handler.openNativeSettings(
- this.app_.id);
- },
-
- /**
- * @param {!Array<ExtensionAppPermissionMessage>} messages
- * @return {Array<string>}
- * @private
- */
- getPermissionMessages_: function(messages) {
- return messages.map(m => m.message);
- },
-
- /**
- * @param {number} index
- * @param {!Array<ExtensionAppPermissionMessage>} messages
- * @return {?Array<string>}
- * @private
- */
- getPermissionSubmessagesByMessage_: function(index, messages) {
- // Dom-repeat still tries to access messages[0] when app has no
- // permission therefore we add an extra check.
- if (!messages[index]) {
- return null;
- }
- return messages[index].submessages;
- },
-
- /**
- * @param {!Array<ExtensionAppPermissionMessage>} messages
- * @return {boolean}
- * @private
- */
- hasPermissions_: function(messages) {
- return messages.length > 0;
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/constants.html b/chromium/chrome/browser/resources/app_management/constants.html
deleted file mode 100644
index 2b6bc6b93e9..00000000000
--- a/chromium/chrome/browser/resources/app_management/constants.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="constants.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/constants.js b/chromium/chrome/browser/resources/app_management/constants.js
deleted file mode 100644
index a3ca5777e9e..00000000000
--- a/chromium/chrome/browser/resources/app_management/constants.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 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.
-
-/**
- * The number of apps displayed in app list in the main view before expanding.
- * @const {number}
- */
-const NUMBER_OF_APPS_DISPLAYED_DEFAULT = 4;
-
-/**
- * The maximum number of apps' titles previewed in notification sublabel.
- * @const {number}
- */
-const APP_LIST_PREVIEW_APP_TITLES = 3;
-
-/**
- * Enumeration of the different subpage types within the app management page.
- * @enum {number}
- * @const
- */
-const PageType = {
- MAIN: 0,
- DETAIL: 1,
- NOTIFICATIONS: 2,
-};
-
-/**
- * A number representation of a Bool. Permission values should be of this type
- * for permissions with value type PermissionValueType.kBool.
- * @enum {number}
- * @const
- */
-const Bool = {
- kFalse: 0,
- kTrue: 1,
-};
-
-const PwaPermissionType = appManagement.mojom.PwaPermissionType;
-
-const ArcPermissionType = appManagement.mojom.ArcPermissionType;
-
-const AppType = apps.mojom.AppType;
-
-const PermissionValueType = apps.mojom.PermissionValueType;
-
-const TriState = apps.mojom.TriState;
-
-const OptionalBool = apps.mojom.OptionalBool;
-
-const InstallSource = apps.mojom.InstallSource;
diff --git a/chromium/chrome/browser/resources/app_management/dom_switch.html b/chromium/chrome/browser/resources/app_management/dom_switch.html
deleted file mode 100644
index 23af2ec0fbc..00000000000
--- a/chromium/chrome/browser/resources/app_management/dom_switch.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<dom-module id="app-management-dom-switch">
- <template>
- <slot></slot>
- </template>
- <script src="dom_switch.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/dom_switch.js b/chromium/chrome/browser/resources/app_management/dom_switch.js
deleted file mode 100644
index b5117bf76ce..00000000000
--- a/chromium/chrome/browser/resources/app_management/dom_switch.js
+++ /dev/null
@@ -1,128 +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
- * app-management-dom-switch is used to select one element to be displayed at a
- * time from a group of elements. When an element is selected, it is attached
- * to the DOM. When another element is selected, the first element is
- * detached, meaning only one of the elements is attached at a time.
- *
- * The elements are selected by giving them each a route-id attribute, then
- * setting the route property of the dom-switch equal to the route-id of the
- * element to be shown.
- *
- * Data binding from the parent element of the dom-switch to its child
- * elements works as usual.
- *
- * Usage:
- * <parent-element>
- * <app-management-dom-switch id="view-selector">
- * <template>
- * <view-one route-id="view-one" title="[[parentProperty]]"></view-one>
- * <view-two route-id="view-two"></view-two>
- * <view-three route-id="view-three"></view-three>
- * </template>
- * </app-management-dom-switch>
- * </parent-element>
- *
- * this.$['view-selector'].route = 'view-two';
- */
-
-Polymer({
- is: 'app-management-dom-switch',
-
- behaviors: [Polymer.Templatizer],
-
- properties: {
- /**
- * Should contain the route-id of one of the elements within the dom-switch.
- * @private {?string}
- */
- route: {
- type: String,
- observer: 'onRouteChanged_',
- },
-
- /**
- * The template instance.
- * @private {?Element}
- */
- instance_: {
- type: Object,
- value: null,
- },
-
- /**
- * Maps the route-id of each element within the dom-switch to the element
- * itself.
- * @private {Object<string, Element>}
- */
- children_: {
- type: Object,
- value: () => ({}),
- },
-
- /**
- * The element whose route-id corresponds to the current route. This is the
- * only element within the dom-switch which is attached to the DOM.
- * @private {?Element}
- */
- selectedChild_: {
- type: Object,
- value: null,
- },
- },
-
- firstRenderForTesting_: new PromiseResolver(),
-
- attached: function() {
- const template = this.getContentChildren()[0];
- this.templatize(template);
-
- // This call stamps all the child elements of the dom-switch at once
- // (calling their created Polymer lifecycle callbacks). If optimisations
- // are required in the future, it may be possible to only stamp children
- // on demand as they are rendered.
- this.instance_ = this.stamp({});
-
- const children = this.instance_.root.children;
- for (const child of children) {
- this.children_[child.getAttribute('route-id')] = child;
- }
- },
-
- /**
- * @param {string} newRouteId
- */
- onRouteChanged_: function(newRouteId) {
- if (!this.instance_) {
- return;
- }
-
- const newSelectedChild = this.children_[newRouteId];
- assert(
- newSelectedChild,
- 'The route must be equal to the route-id of a child element.');
-
- if (this.selectedChild_) {
- this.parentNode.replaceChild(newSelectedChild, this.selectedChild_);
- } else {
- this.parentNode.insertBefore(newSelectedChild, this);
- }
-
- this.selectedChild_ = newSelectedChild;
- this.firstRenderForTesting_.resolve();
- },
-
- /**
- * @param {string} prop
- * @param {Object} value
- */
- _forwardHostPropV2: function(prop, value) {
- if (this.instance_) {
- this.instance_.forwardHostProp(prop, value);
- }
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/expandable_app_list.html b/chromium/chrome/browser/resources/app_management/expandable_app_list.html
index 88558d0c8d1..189b4c08822 100644
--- a/chromium/chrome/browser/resources/app_management/expandable_app_list.html
+++ b/chromium/chrome/browser/resources/app_management/expandable_app_list.html
@@ -4,7 +4,6 @@
<link rel="import" href="constants.html">
<link rel="import" href="shared_style.html">
<link rel="import" href="store_client.html">
-<link rel="import" href="permission_toggle.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
diff --git a/chromium/chrome/browser/resources/app_management/fake_page_handler.js b/chromium/chrome/browser/resources/app_management/fake_page_handler.js
deleted file mode 100644
index 6c8b2492ded..00000000000
--- a/chromium/chrome/browser/resources/app_management/fake_page_handler.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2018 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('app_management', function() {
- /**
- * @implements {appManagement.mojom.PageHandlerInterface}
- */
- class FakePageHandler {
- /**
- * @param {Object=} options
- * @return {!Object<number, Permission>}
- */
- static createWebPermissions(options) {
- const permissionIds = [
- PwaPermissionType.CONTENT_SETTINGS_TYPE_GEOLOCATION,
- PwaPermissionType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
- PwaPermissionType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
- PwaPermissionType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
- ];
-
- const permissions = {};
-
- for (const permissionId of permissionIds) {
- let permissionValue = TriState.kAllow;
- let isManaged = false;
-
- if (options && options[permissionId]) {
- const opts = options[permissionId];
- permissionValue = opts.permissionValue || permissionValue;
- isManaged = opts.isManaged || isManaged;
- }
- permissions[permissionId] = app_management.util.createPermission(
- permissionId, PermissionValueType.kTriState, permissionValue,
- isManaged);
- }
-
- return permissions;
- }
-
- /**
- * @param {Array<number>=} optIds
- * @return {!Object<number, Permission>}
- */
- static createArcPermissions(optIds) {
- const permissionIds = optIds || [
- ArcPermissionType.CAMERA,
- ArcPermissionType.LOCATION,
- ArcPermissionType.MICROPHONE,
- ArcPermissionType.NOTIFICATIONS,
- ArcPermissionType.CONTACTS,
- ArcPermissionType.STORAGE,
- ];
-
- const permissions = {};
-
- for (const permissionId of permissionIds) {
- permissions[permissionId] = app_management.util.createPermission(
- permissionId, PermissionValueType.kBool, Bool.kTrue,
- false /*is_managed*/);
- }
-
- return permissions;
- }
-
- /**
- * @param {AppType} appType
- * @return {!Object<number, Permission>}
- */
- static createPermissions(appType) {
- switch (appType) {
- case (AppType.kWeb):
- return FakePageHandler.createWebPermissions();
- case (AppType.kArc):
- return FakePageHandler.createArcPermissions();
- default:
- return {};
- }
- }
-
- /**
- * @param {string} id
- * @param {Object=} optConfig
- * @return {!App}
- */
- static createApp(id, optConfig) {
- const app = {
- id: id,
- type: apps.mojom.AppType.kWeb,
- title: 'App Title',
- description: '',
- version: '5.1',
- size: '9.0MB',
- isPinned: apps.mojom.OptionalBool.kFalse,
- isPolicyPinned: apps.mojom.OptionalBool.kFalse,
- installSource: apps.mojom.InstallSource.kUser,
- permissions: {},
- hideMoreSettings: false,
- hidePinToShelf: false,
- };
-
- if (optConfig) {
- Object.assign(app, optConfig);
- }
-
- // Only create default permissions if none were provided in the config.
- if (!optConfig || optConfig.permissions === undefined) {
- app.permissions = FakePageHandler.createPermissions(app.type);
- }
-
- return app;
- }
-
- /**
- * @param {appManagement.mojom.PageRemote} page
- */
- constructor(page) {
- this.receiver_ = new appManagement.mojom.PageHandlerReceiver(this);
- /** @type {appManagement.mojom.PageRemote} */
- this.page = page;
-
- /** @type {!Array<App>} */
- this.apps_ = [];
-
- /** @type {number} */
- this.guid = 0;
- }
-
- /**
- * @returns {!appManagement.mojom.PageHandlerRemote}
- */
- getRemote() {
- return this.receiver_.$.bindNewPipeAndPassRemote();
- }
-
- async flushPipesForTesting() {
- await this.page.$.flushForTesting();
- }
-
- async getApps() {
- return {apps: this.apps_};
- }
-
- /**
- * @param {string} appId
- * @return {!Promise}
- */
- async getExtensionAppPermissionMessages(appId) {
- return [];
- }
-
- /**
- * @param {!Array<App>} appList
- */
- setApps(appList) {
- this.apps_ = appList;
- }
-
- /**
- * @param {string} appId
- * @param {OptionalBool} pinnedValue
- */
- setPinned(appId, pinnedValue) {
- const app = app_management.Store.getInstance().data.apps[appId];
-
- const newApp =
- /** @type {App} */ (Object.assign({}, app, {isPinned: pinnedValue}));
- this.page.onAppChanged(newApp);
- }
-
- /**
- * @param {string} appId
- * @param {Permission} permission
- */
- setPermission(appId, permission) {
- const app = app_management.Store.getInstance().data.apps[appId];
-
- // Check that the app had a previous value for the given permission
- assert(app.permissions[permission.permissionId]);
-
- const newPermissions = Object.assign({}, app.permissions);
- newPermissions[permission.permissionId] = permission;
- const newApp = /** @type {App} */ (
- Object.assign({}, app, {permissions: newPermissions}));
- this.page.onAppChanged(newApp);
- }
-
- /**
- * @param {string} appId
- */
- uninstall(appId) {
- this.page.onAppRemoved(appId);
- }
-
- /**
- * @param {string} appId
- */
- openNativeSettings(appId) {}
-
- /**
- * @param {string} optId
- * @param {Object=} optConfig
- * @return {!Promise<!App>}
- */
- async addApp(optId, optConfig) {
- optId = optId || String(this.guid++);
- const app = FakePageHandler.createApp(optId, optConfig);
- this.page.onAppAdded(app);
- await this.flushPipesForTesting();
- return app;
- }
-
- /**
- * Takes an app id and an object mapping app fields to the values they
- * should be changed to, and dispatches an action to carry out these
- * changes.
- * @param {string} id
- * @param {Object} changes
- */
- async changeApp(id, changes) {
- this.page.onAppChanged(FakePageHandler.createApp(id, changes));
- await this.flushPipesForTesting();
- }
- }
-
- return {FakePageHandler: FakePageHandler};
-});
diff --git a/chromium/chrome/browser/resources/app_management/icons.html b/chromium/chrome/browser/resources/app_management/icons.html
deleted file mode 100644
index ccb16326e6b..00000000000
--- a/chromium/chrome/browser/resources/app_management/icons.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<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="app-management" size="24">
- <svg>
- <!--
- These icons are copied from material.io and kept in sorted order.
- See http://goo.gl/Y1OdAq for instructions on adding additional icons.
- -->
- <defs>
- <!-- From https://material.io/tools/icons/?icon=account_box&style=baseline -->
- <g id="contacts"><path d="M19 3H5c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5a2 2 0 0 0-2-2zm-7 3c1.65 0 3 1.35 3 3 0 1.66-1.35 3-3 3s-3-1.34-3-3c0-1.65 1.35-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z"></path><path fill="none" d="M0 0h24v24H0z"></path></g>
- <!-- From https://material.io/tools/icons/?icon=storage&style=baseline -->
- <g id="storage"><path d="M2 20h20v-4H2v4zm2-3h2v2H4v-2zM2 4v4h20V4H2zm4 3H4V5h2v2zm-4 7h20v-4H2v4zm2-3h2v2H4v-2z"></path></g>
- </defs>
- </svg>
-</iron-iconset-svg>
diff --git a/chromium/chrome/browser/resources/app_management/main_view.html b/chromium/chrome/browser/resources/app_management/main_view.html
deleted file mode 100644
index 364a6702961..00000000000
--- a/chromium/chrome/browser/resources/app_management/main_view.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="expandable_app_list.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-
-<dom-module id="app-management-main-view">
- <template>
- <style include="app-management-shared-css">
- .notification-row-sublabel {
- display: flex;
- flex-direction: column;
- overflow: hidden;
- padding: 11px 0;
- }
-
- .collapsible {
- max-width: 250px;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- #notifications-sublabel {
- display: flex;
- overflow: hidden;
- }
-
- #notifications-sublabel > span {
- white-space: pre;
- }
-
- .notification-row {
- align-items: center;
- cursor: pointer;
- display: inline-flex;
- justify-content: space-between;
- padding: 0 24px;
- }
-
- .app-management-item-arrow {
- margin-inline-end: 8px;
- padding: 12px;
- }
- </style>
- <app-management-expandable-app-list
- apps="[[appsList]]"
- list-title="$i18n{appListTitle}"
- collapsed-size="[[appsList.length]]">
- <template is="dom-repeat" items="[[appsList]]" as="app">
- <app-management-app-item app="[[app]]">
- <cr-icon-button slot="right-content"
- class="subpage-arrow app-management-item-arrow" actionable>
- </cr-icon-button>
- </app-management-app-item>
- </template>
- </app-management-expandable-app-list>
-
- <div class="card-container" hidden>
- <span class="notification-row" on-click="onClickNotificationSublabel_">
- <div class="notification-row-sublabel">
- <div class="header-text">
- $i18n{notifications}
- </div>
- <div id="notifications-sublabel" class="secondary-text"></div>
- </div>
- <cr-icon-button class="subpage-arrow" actionable></cr-icon-button>
- </span>
- </div>
- </template>
- <script src="main_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/main_view.js b/chromium/chrome/browser/resources/app_management/main_view.js
deleted file mode 100644
index de2073cb289..00000000000
--- a/chromium/chrome/browser/resources/app_management/main_view.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2018 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.
-
-Polymer({
- is: 'app-management-main-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * @private {AppMap}
- */
- apps_: {
- type: Object,
- observer: 'onAppsChanged_',
- },
-
- /**
- * List of apps displayed before expanding the app list.
- * @private {Array<App>}
- */
- appsList: {
- type: Array,
- value: () => [],
- },
-
- /**
- * A set containing the ids of all the apps with notifications enabled.
- * @private {!Set<string>}
- */
- notificationAppIds_: {
- type: Object,
- observer: 'getNotificationSublabel_',
- },
- },
-
- attached: function() {
- this.watch('apps_', state => state.apps);
- this.watch('notificationAppIds_', state => state.notifications.allowedIds);
- this.updateFromStore();
- this.onAppsChanged_();
- },
-
- /**
- * @private
- */
- onAppsChanged_: function() {
- this.appsList = Object.values(this.apps_)
- .sort(
- (a, b) => app_management.util.alphabeticalSort(
- assert(a.title), assert(b.title)));
- },
-
- /** @private */
- onClickNotificationSublabel_: function() {
- this.dispatch(app_management.actions.changePage(PageType.NOTIFICATIONS));
- },
-
- /**
- * Show a string with apps' |title|(s) previewed into a label, with each
- * title ellipsised if too long.
- * @private
- */
- getNotificationSublabelPieces_: async function() {
- const notificationApps =
- Array.from(this.notificationAppIds_, id => this.getState().apps[id]);
-
- const /** @type {string} */ label = await cr.sendWithPromise(
- 'getPluralString', 'appListPreview', notificationApps.length);
-
- const substitutions = [];
- for (let i = 0;
- i < APP_LIST_PREVIEW_APP_TITLES && i < notificationApps.length; i++) {
- substitutions.push(notificationApps[i].title);
- }
-
- // Add X more apps if the length is more than APP_LIST_PREVIEW_APP_TITLES.
- if (notificationApps.length >= APP_LIST_PREVIEW_APP_TITLES + 1) {
- substitutions.push(notificationApps.length - APP_LIST_PREVIEW_APP_TITLES);
- }
- // Only APP_LIST_PREVIEW_APP_TITLES of apps' titles get ellipsised
- // if too long. the element after that is "X other apps"
- const placeholder = APP_LIST_PREVIEW_APP_TITLES + 1;
- const pieces =
- loadTimeData.getSubstitutedStringPieces(label, ...substitutions)
- .map(function(p) {
- // Make the titles of app collapsible but make the number in the
- // "X other app(s)" part non-collapsible.
- p.collapsible = !!p.arg && p.arg !== '$' + placeholder;
- return p;
- });
- return pieces;
- },
-
- /**
- * Create <span> for each app title previewed,
- * making certain text fragments collapsible.
- */
- getNotificationSublabel_: async function() {
- const pieces = await this.getNotificationSublabelPieces_();
- // Create <span> for each app title previewed,
- // making certain text fragments collapsible.
- const textContainer = this.$['notifications-sublabel'];
- textContainer.textContent = '';
- for (const p of pieces) {
- if (!p.value || p.value.length === 0) {
- return;
- }
-
- const span = document.createElement('span');
- span.textContent = p.value;
- if (p.collapsible) {
- span.classList.add('collapsible');
- }
-
- textContainer.appendChild(span);
- }
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/metadata_view.html b/chromium/chrome/browser/resources/app_management/metadata_view.html
deleted file mode 100644
index 43948aeb5f3..00000000000
--- a/chromium/chrome/browser/resources/app_management/metadata_view.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="browser_proxy.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-
-<dom-module id="app-management-metadata-view">
- <template>
- <style include="app-management-shared-css">
- #shelf-switch-row {
- align-items: center;
- display: flex;
- justify-content: space-around;
- padding-bottom: 20px;
- }
-
- #shelf-switch {
- align-items: center;
- display: flex;
- justify-content: space-between;
- }
-
- cr-toggle {
- margin-inline-start: 12px;
- }
-
- #metadata-overview {
- display: flex;
- flex-direction: column;
- }
-
- #metadata-overview > span {
- text-align: center;
- }
-
- .metadata-row {
- display: flex;
- justify-content: space-around;
- }
-
- #policy-indicator {
- fill: var(--google-grey-refresh-700);
- margin-inline-end: 12px;
- }
- </style>
- <template is="dom-if" if="[[pinToShelfToggleVisible_(app_)]]">
- <div id="shelf-switch-row">
- <span id="shelf-switch" class="header-text">
- <template is="dom-if" if="[[isPolicyPinned_(app_)]]">
- <iron-icon id="policy-indicator" icon="cr:domain" tabindex="0"
- aria-describedby="tooltip">
- </iron-icon>
- <paper-tooltip id="tooltip" for="policy-indicator"
- position="top" fit-to-visible-bounds>
- $i18n{pinControlledByPolicy}
- </paper-tooltip>
- </template>
- $i18n{pinToShelf}
- <cr-toggle id="pin-to-shelf-toggle" checked="[[isPinned_(app_)]]"
- on-change="togglePinned_" disabled$="[[isPolicyPinned_(app_)]]">
- </cr-toggle>
- </span>
- </div>
- </template>
-
- <div id="metadata-overview" class="secondary-text">
- <span>[[versionString_(app_)]]</span>
- <span>[[sizeString_(app_)]]</span>
- </div>
- </template>
- <script src="metadata_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/metadata_view.js b/chromium/chrome/browser/resources/app_management/metadata_view.js
deleted file mode 100644
index d063cdc2196..00000000000
--- a/chromium/chrome/browser/resources/app_management/metadata_view.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2018 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.
-
-Polymer({
- is: 'app-management-metadata-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /** @type {App} */
- app_: {
- type: Object,
- },
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.updateFromStore();
- },
-
- /**
- * @param {App} app
- * @return bool
- * @private
- */
- pinToShelfToggleVisible_: function(app) {
- return app.isPinned !== OptionalBool.kUnknown;
- },
-
- /**
- * Returns a bool representation of the app's isPinned value, used to
- * determine the position of the "Pin to Shelf" toggle.
- * @param {App} app
- * @return bool
- * @private
- */
- isPinned_: function(app) {
- return app.isPinned === OptionalBool.kTrue;
- },
-
- isPolicyPinned_: function(app) {
- return app.isPolicyPinned === OptionalBool.kTrue;
- },
-
- /** @private */
- togglePinned_: function() {
- let newPinnedValue;
-
- switch (this.app_.isPinned) {
- case OptionalBool.kFalse:
- newPinnedValue = OptionalBool.kTrue;
- break;
- case OptionalBool.kTrue:
- newPinnedValue = OptionalBool.kFalse;
- break;
- default:
- assertNotReached();
- }
-
- app_management.BrowserProxy.getInstance().handler.setPinned(
- this.app_.id, assert(newPinnedValue));
- },
-
- /**
- * @param {App} app
- * @return {?string}
- * @private
- */
- versionString_: function(app) {
- if (!app.version) {
- return null;
- }
-
- return loadTimeData.getStringF('version', assert(app.version));
- },
-
- /**
- * @param {App} app
- * @return {?string}
- * @private
- */
- sizeString_: function(app) {
- if (!app.size) {
- return null;
- }
-
- return loadTimeData.getStringF('size', assert(app.size));
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/notifications_view.html b/chromium/chrome/browser/resources/app_management/notifications_view.html
deleted file mode 100644
index c66bcb2ce6c..00000000000
--- a/chromium/chrome/browser/resources/app_management/notifications_view.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="expandable_app_list.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-
-<dom-module id="app-management-notifications-view">
- <template>
- <style include="app-management-shared-css">
- cr-icon-button {
- margin: 0;
- }
-
- app-management-permission-toggle {
- margin-inline-end: 24px;
- }
-
- #notification-view-header {
- align-items: center;
- display: flex;
- margin: 24px auto;
- max-width: var(--card-max-width);
- min-width: var(--card-min-width);
- }
-
- #notification-title {
- padding-inline-start: 12px;
- }
- </style>
- <!-- TODO(crbug.com/906508): Implement display when there is no apps at
- all -->
- <div id="notification-view-header">
- <cr-icon-button class="icon-arrow-back" id="closeButton"
- on-click="onClickBackButton_" aria-label="$i18n{back}">
- </cr-icon-button>
- <div id="notification-title" class="page-title">$i18n{notifications}</div>
- </div>
- <app-management-expandable-app-list
- apps="[[appsList_]]"
- collapsed-size="[[getCollapsedSize_(appsList_)]]">
- <template is="dom-repeat" items="[[appsList_]]" as="app">
- <app-management-app-item app="[[app]]">
- <app-management-permission-toggle slot="right-content"
- app="[[app]]"
- permission-type="CONTENT_SETTINGS_TYPE_NOTIFICATIONS">
- </app-management-permission-toggle>
- </app-management-app-item>
- </template>
- </app-management-expandable-app-list>
- </template>
- <script src="notifications_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/notifications_view.js b/chromium/chrome/browser/resources/app_management/notifications_view.js
deleted file mode 100644
index aae8cffaf05..00000000000
--- a/chromium/chrome/browser/resources/app_management/notifications_view.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2018 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.
-
-Polymer({
- is: 'app-management-notifications-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * @private {AppMap}
- */
- apps_: {
- type: Object,
- observer: 'onAppsChanged_',
- },
-
- /** @private {!Array<!App>} */
- appsList_: {
- type: Array,
- computed: 'calculateAppsList_(allowed_.*, blocked_.*)',
- },
-
- /**
- * List of apps with notification permission
- * displayed before expanding the app list.
- * @private {!Array<App>}
- */
- allowed_: {
- type: Array,
- value: () => [],
- },
-
- /**
- * List of apps without notification permission
- * displayed after expanding app list.
- * @private {!Array<App>}
- */
- blocked_: {
- type: Array,
- value: () => [],
- },
- },
-
- attached: function() {
- this.watch('apps_', state => state.apps);
- this.updateFromStore();
-
- this.onViewLoaded_();
- },
-
- /**
- * Creates arrays of displayed and collapsed apps based on the sets of apps
- * with notifications allowed and blocked in the Store. The orders of apps
- * in these arrays should then remain fixed while this view is showing.
- *
- * If all the apps have / don't have notification permission, display the
- * whole list, else display those with notification permission before
- * expanding.
- * @private
- */
- onViewLoaded_: function() {
- const state = this.getState();
- this.allowed_ =
- Array.from(state.notifications.allowedIds, id => state.apps[id]);
- this.blocked_ =
- Array.from(state.notifications.blockedIds, id => state.apps[id]);
- },
-
- /**
- * Updates the lists of displayed and collapsed apps when any changes occur
- * to the apps in the Store, maintaining the original order of apps in the
- * lists. New lists are created so that Polymer bindings will re-evaluate.
- * @private
- */
- onAppsChanged_() {
- const unhandledAppIds = new Set(Object.keys(this.apps_));
- this.allowed_ = this.updateAppList_(this.allowed_, unhandledAppIds);
- this.blocked_ = this.updateAppList_(this.blocked_, unhandledAppIds);
-
- // If any new apps have been added, append them to the appropriate list.
- for (const appId of unhandledAppIds) {
- const app = this.apps_[appId];
- const allowed = app_management.util.notificationsAllowed(app);
-
- if (allowed === OptionalBool.kUnknown) {
- continue;
- }
-
- if (allowed === OptionalBool.kTrue) {
- this.push('allowed_', app);
- } else {
- this.push('blocked_', app);
- }
- }
- },
-
- /**
- * @private
- * @return {!Array<!App>}
- */
- calculateAppsList_() {
- return this.allowed_.concat(this.blocked_);
- },
-
- /**
- * @private
- * @return {number}
- */
- getCollapsedSize_() {
- return this.allowed_.length || this.blocked_.length;
- },
-
- /**
- * Creates a new list of apps with the same order as the original appList,
- * but using the updated apps from this.apps_. As each app is added to the
- * new list, it is also removed from the unhandledAppIds set.
- * @param {!Array<App>} appList
- * @param {!Set<string>} unhandledAppIds
- * @return {!Array<App>}
- * @private
- */
- updateAppList_(appList, unhandledAppIds) {
- const newApps = [];
- for (const app of appList) {
- if (unhandledAppIds.has(app.id)) {
- newApps.push(this.apps_[app.id]);
- unhandledAppIds.delete(app.id);
- }
- }
- return newApps;
- },
-
- /** @private */
- onClickBackButton_: function() {
- if (!window.history.state) {
- this.dispatch(app_management.actions.changePage(PageType.MAIN));
- } else {
- window.history.back();
- }
- },
-
- /**
- * Returns a boolean representation of the permission value, which used to
- * determine the position of the permission toggle.
- * @param {App} app
- * @return {boolean}
- * @private
- */
- getNotificationValueBool_: function(app) {
- return app_management.util.getPermissionValueBool(
- app, this.notificationsPermissionType(app));
- },
-
- /**
- * @param {App} app
- * @return {string}
- * @private
- */
- notificationsPermissionType_: function(app) {
- return assert(app_management.util.notificationsPermissionType(app));
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/permission_item.html b/chromium/chrome/browser/resources/app_management/permission_item.html
deleted file mode 100644
index 915351268c6..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_item.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="shared_style.html">
-<link rel="import" href="permission_toggle.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-
-<dom-module id="app-management-permission-item">
- <template>
- <style include="app-management-shared-css">
- :host {
- align-items: center;
- cursor: pointer;
- display: flex;
- justify-content: space-between;
- }
-
- :host(:not([available_])) {
- display: none;
- }
-
- #permission-icon {
- color: var(--permission-icon-color);
- padding-inline-end: var(--permission-icon-padding);
- }
- </style>
- <!-- `permission-item` does not include any icon-set, so containing
- elements should import the icon-set needed for the specified |icon|. -->
- <template is="dom-if" if="[[available_]]">
- <div class="permission-row-controls">
- <template is="dom-if" if="[[icon]]">
- <iron-icon id="permission-icon" icon="[[icon]]"></iron-icon>
- </template>
- <div id="permission-label">[[permissionLabel]]</div>
- </div>
- <app-management-permission-toggle id="permission-toggle"
- app="[[app_]]" permission-type="[[permissionType]]">
- </app-management-permission-toggle>
- </template>
- </template>
- <script src="permission_item.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/permission_item.js b/chromium/chrome/browser/resources/app_management/permission_item.js
deleted file mode 100644
index cf610ef9bcb..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_item.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-permission-item',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * The name of the permission, to be displayed to the user.
- * @type {string}
- */
- permissionLabel: String,
-
- /**
- * A string version of the permission type. Must be a value of the
- * permission type enum corresponding to the AppType of app_.
- * E.g. A value of PwaPermissionType if app_.type === AppType.kWeb.
- * @type {string}
- */
- permissionType: String,
-
- /**
- * @type {App}
- */
- app_: Object,
-
- /**
- * @type {string}
- */
- icon: String,
-
- /**
- * True if the permission type is available for the app.
- * @private
- */
- available_: {
- type: Boolean,
- computed: 'isAvailable_(app_, permissionType)',
- reflectToAttribute: true,
- },
- },
-
- listeners: {
- 'click': 'onClick_',
- },
-
- /**
- * Returns true if the permission type is available for the app.
- *
- * @param {App} app
- * @param {string} permissionType
- * @private
- */
- isAvailable_: function(app, permissionType) {
- if (app === undefined || permissionType === undefined) {
- return false;
- }
-
- assert(app);
-
- return app_management.util.getPermission(app, permissionType) !== undefined;
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.updateFromStore();
- },
-
- /**
- * @param {MouseEvent} e
- * @private
- */
- onClick_: function(e) {
- e.preventDefault();
-
- const toggle = /** @type {AppManagementPermissionToggleElement} */ (
- assert(this.$$('#permission-toggle')));
- toggle.togglePermission_();
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/permission_toggle.html b/chromium/chrome/browser/resources/app_management/permission_toggle.html
deleted file mode 100644
index 7086ec640ad..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_toggle.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-
-<!-- TODO(jshikaram): use toggle-row here. -->
-
-<dom-module id="app-management-permission-toggle">
- <template>
- <style>
- :host {
- align-items: center;
- display: flex;
- }
-
- #policy-indicator {
- fill: var(--google-grey-refresh-700);
- padding-inline-end: 12px;
- }
- </style>
- <template is="dom-if"
- if="[[isPermissionManaged_(app, permissionType)]]">
- <iron-icon id="policy-indicator" icon="cr:domain" tabindex="0"
- aria-describedby="tooltip">
- </iron-icon>
- <paper-tooltip id="tooltip" for="policy-indicator"
- position="top" fit-to-visible-bounds>
- $i18n{controlledByPolicy}
- </paper-tooltip>
- </template>
- <cr-toggle checked="[[getPermissionValueBool_(app, permissionType)]]"
- on-change="togglePermission_"
- disabled$="[[isPermissionManaged_(app, permissionType)]]">
- </cr-toggle>
- </template>
- <script src="permission_toggle.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/permission_toggle.js b/chromium/chrome/browser/resources/app_management/permission_toggle.js
deleted file mode 100644
index 7856395ea6f..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_toggle.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-permission-toggle',
-
- properties: {
- /**
- * @type {App}
- */
- app: Object,
-
- /**
- * A string version of the permission type. Must be a value of the
- * permission type enum corresponding to the AppType of app_.
- * E.g. A value of PwaPermissionType if app_.type === AppType.kWeb.
- * @type {string}
- */
- permissionType: String,
- },
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {boolean}
- */
- getPermissionValueBool_: function(app, permissionType) {
- if (app === undefined || permissionType === undefined) {
- return false;
- }
-
- assert(app);
-
- return app_management.util.getPermissionValueBool(app, permissionType);
- },
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {boolean}
- */
- isPermissionManaged_: function(app, permissionType) {
- if (app === undefined || permissionType === undefined) {
- return false;
- }
-
- assert(app);
-
- const permission = app_management.util.getPermission(app, permissionType);
- assert(permission);
- return permission.isManaged;
- },
-
- togglePermission_: function() {
- assert(this.app);
-
- /** @type {!Permission} */
- let newPermission;
-
- switch (app_management.util.getPermission(this.app, this.permissionType)
- .valueType) {
- case PermissionValueType.kBool:
- newPermission =
- this.getNewPermissionBoolean_(this.app, this.permissionType);
- break;
- case PermissionValueType.kTriState:
- newPermission =
- this.getNewPermissionTriState_(this.app, this.permissionType);
- break;
- default:
- assertNotReached();
- }
-
- app_management.BrowserProxy.getInstance().handler.setPermission(
- this.app.id, newPermission);
- },
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {!Permission}
- * @private
- */
- getNewPermissionBoolean_: function(app, permissionType) {
- let newPermissionValue;
- const currentPermission =
- app_management.util.getPermission(app, permissionType);
-
- switch (currentPermission.value) {
- case Bool.kFalse:
- newPermissionValue = Bool.kTrue;
- break;
- case Bool.kTrue:
- newPermissionValue = Bool.kFalse;
- break;
- default:
- assertNotReached();
- }
-
- assert(newPermissionValue !== undefined);
- return app_management.util.createPermission(
- app_management.util.permissionTypeHandle(app, permissionType),
- PermissionValueType.kBool, newPermissionValue,
- currentPermission.isManaged);
- },
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {!Permission}
- * @private
- */
- getNewPermissionTriState_: function(app, permissionType) {
- let newPermissionValue;
- const currentPermission =
- app_management.util.getPermission(app, permissionType);
-
- switch (currentPermission.value) {
- case TriState.kBlock:
- newPermissionValue = TriState.kAllow;
- break;
- case TriState.kAsk:
- newPermissionValue = TriState.kAllow;
- break;
- case TriState.kAllow:
- // TODO(rekanorman): Eventually TriState.kAsk, but currently changing a
- // permission to kAsk then opening the site settings page for the app
- // produces the error:
- // "Only extensions or enterprise policy can change the setting to ASK."
- newPermissionValue = TriState.kBlock;
- break;
- default:
- assertNotReached();
- }
-
- assert(newPermissionValue !== undefined);
- return app_management.util.createPermission(
- app_management.util.permissionTypeHandle(app, permissionType),
- PermissionValueType.kTriState, newPermissionValue,
- currentPermission.isManaged);
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/permission_view_header.html b/chromium/chrome/browser/resources/app_management/permission_view_header.html
deleted file mode 100644
index d0c6f0c9e55..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_view_header.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="shared_style.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-
-<dom-module id="app-management-permission-view-header">
- <template>
- <style include="app-management-shared-css">
- :host {
- align-items: center;
- display: flex;
- margin: 24px auto;
- max-width: var(--card-max-width);
- min-width: var(--card-min-width);
- }
-
- #permission-view-header-icon {
- height: 26px;
- margin-inline-end: 8px;
- margin-inline-start: 24px;
- width: 26px;
- }
-
- #app-title {
- flex: 1;
- font-size: 16px;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- cr-icon-button {
- margin: 0;
- }
-
- #uninstall-button {
- background: white;
- }
-
- #policy-indicator {
- fill: var(--google-grey-refresh-700);
- margin-inline-end: 12px;
- }
- </style>
- <cr-icon-button class="icon-arrow-back" id="backButton"
- on-click="onClickBackButton_" aria-label="$i18n{back}"></cr-icon-button>
- <img id="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]">
- <div class="page-title">[[app_.title]]</div>
-
- <div id="uninstall-wrapper" title$="[[getUninstallButtonHoverText_(app_)]]">
- <template is="dom-if" if="[[isPolicyApp_(app_)]]">
- <iron-icon id="policy-indicator" icon="cr:domain"></iron-icon>
- </template>
- <cr-button id="uninstall-button" on-click="onClickUninstallButton_"
- disabled$="[[getUninstallButtonDisableState_(app_)]]">
- $i18n{uninstall}
- </cr-button>
- </div>
- </template>
- <script src="permission_view_header.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/permission_view_header.js b/chromium/chrome/browser/resources/app_management/permission_view_header.js
deleted file mode 100644
index a6caf895c2e..00000000000
--- a/chromium/chrome/browser/resources/app_management/permission_view_header.js
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-permission-view-header',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /** @type {App} */
- app_: {
- type: Object,
- },
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.updateFromStore();
- },
-
- /**
- *
- * Returns True if the uninstall button should be disabled due to app install
- * type.
- *
- * @param {App} app
- * @return {boolean}
- * @private
- */
- getUninstallButtonDisableState_: function(app) {
- switch (app.installSource) {
- case InstallSource.kSystem:
- case InstallSource.kPolicy:
- return true;
- case InstallSource.kOem:
- case InstallSource.kDefault:
- case InstallSource.kSync:
- case InstallSource.kUser:
- case InstallSource.kUnknown:
- return false;
- default:
- assertNotReached();
- }
- },
-
- /**
- * Returns string to be shown as a tool tip over the uninstall button.
- *
- * @param {App} app
- * @return {string}
- * @private
- */
- getUninstallButtonHoverText_: function(app) {
- // TODO(crbug.com/957795) Replace strings and add them into i18n.
- switch (app.installSource) {
- case InstallSource.kSystem:
- return app.title + ' cannot be uninstalled as it is part of Chrome OS.';
- case InstallSource.kPolicy:
- return app.title + ' cannot be uninstalled as it has been' +
- ' installed by your administrator.';
- case InstallSource.kOem:
- case InstallSource.kDefault:
- case InstallSource.kSync:
- case InstallSource.kUser:
- case InstallSource.kUnknown:
- return `Click to uninstall ${app.title}.`;
- default:
- assertNotReached();
- }
- },
-
- /**
- * Returns true if the app was installed by a policy
- *
- * @param {App} app
- * @returns {boolean}
- * @private
- */
- isPolicyApp_: function(app) {
- return app.installSource === InstallSource.kPolicy;
- },
-
- /**
- * @param {App} app
- * @return {string}
- * @private
- */
- iconUrlFromId_: function(app) {
- return app_management.util.getAppIcon(app);
- },
-
- /**
- * @private
- */
- onClickBackButton_: function() {
- if (!window.history.state) {
- this.dispatch(app_management.actions.changePage(PageType.MAIN));
- } else {
- window.history.back();
- }
- },
-
- /**
- * @private
- */
- onClickUninstallButton_: function() {
- app_management.BrowserProxy.getInstance().handler.uninstall(this.app_.id);
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.html b/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.html
deleted file mode 100644
index fe4821f2988..00000000000
--- a/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="toggle_row.html">
-
-<dom-module id="app-management-pin-to-shelf-item">
- <template>
- <style>
- :host(:not([disabled])) {
- cursor: pointer;
- }
- </style>
- <app-management-toggle-row
- label_="$i18n{pinToShelf}"
- managed_$="[[isManaged_(app_)]]"
- policy-label_="$i18n{pinControlledByPolicy}"
- value_$="[[getValue_(app_)]]">
- </app-management-toggle-row>
- </template>
- <script src="pin_to_shelf_item.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.js b/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.js
deleted file mode 100644
index ee5d2ac0df4..00000000000
--- a/chromium/chrome/browser/resources/app_management/pin_to_shelf_item.js
+++ /dev/null
@@ -1,95 +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.
-Polymer({
- is: 'app-management-pin-to-shelf-item',
-
- properties: {
- /**
- * @type {App}
- * @private
- */
- app_: Object,
-
- /**
- * @type {boolean}
- * @private
- */
- hidden: {
- type: Boolean,
- computed: 'isAvailable_(app_)',
- reflectToAttribute: true,
- },
-
- /**
- * @type {boolean}
- * @private
- */
- disabled: {
- type: Boolean,
- computed: 'isManaged_(app_)',
- reflectToAttribute: true,
- },
- },
-
- ready: function() {
- // capture the onClick event before it reaches the toggle.
- this.addEventListener('click', this.onClick_, true);
- },
-
- /**
- * @param {App} app
- * @returns {boolean} true if the app is pinned
- * @private
- */
- getValue_: function(app) {
- if (app === undefined) {
- return false;
- }
- assert(app);
- return app.isPinned === OptionalBool.kTrue;
- },
-
- /**
- * @param {App} app
- * @returns {boolean} true if pinning is available.
- */
- isAvailable_: function(app) {
- if (app === undefined) {
- return false;
- }
- assert(app);
- return app.hidePinToShelf;
- },
-
- /**
- * @param {App} app
- * @returns {boolean} true if the pinning is managed by policy.
- * @private
- */
- isManaged_: function(app) {
- if (app === undefined) {
- return false;
- }
- assert(app);
- return app.isPolicyPinned === OptionalBool.kTrue;
- },
-
- /**
- * @param {Event} event
- * @private
- */
- onClick_: function(event) {
- event.stopPropagation();
-
- // Disabled
- if (this.isManaged_(this.app_)) {
- return;
- }
-
- app_management.BrowserProxy.getInstance().handler.setPinned(
- this.app_.id,
- assert(app_management.util.toggleOptionalBool(this.app_.isPinned)),
- );
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/pwa_permission_view.html b/chromium/chrome/browser/resources/app_management/pwa_permission_view.html
deleted file mode 100644
index 17952e85e3f..00000000000
--- a/chromium/chrome/browser/resources/app_management/pwa_permission_view.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="browser_proxy.html">
-<link rel="import" href="metadata_view.html">
-<link rel="import" href="permission_item.html">
-<link rel="import" href="permission_view_header.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="pin_to_shelf_item.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-
-<dom-module id="app-management-pwa-permission-view">
- <template>
- <style include="app-management-shared-css">
- </style>
-
- <app-management-permission-view-header>
- </app-management-permission-view-header>
-
- <div class="permission-list card-container">
- <app-management-pin-to-shelf-item
- id="pin-to-shelf-setting"
- class="permission-card-row separated-row header-text"
- app_="[[app_]]">
- </app-management-pin-to-shelf-item>
- <app-management-permission-item id="notifications-card"
- class="permission-card-row separated-row header-text"
- permission-label="$i18n{notifications}"
- permission-type="CONTENT_SETTINGS_TYPE_NOTIFICATIONS">
- </app-management-permission-item>
- <div id="permissions-card" class="permission-card-row">
- <div class="subpermission-list">
- <div class="subpermission-row separated-row">
- <div class="header-text">$i18n{permissions}</div>
- </div>
- <app-management-permission-item id="location"
- class="subpermission-row" icon="cr:location-on"
- permission-label="$i18n{location}"
- permission-type="CONTENT_SETTINGS_TYPE_GEOLOCATION">
- </app-management-permission-item>
- <app-management-permission-item id="camera" class="subpermission-row"
- icon="cr:videocam" permission-label="$i18n{camera}"
- permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA">
- </app-management-permission-item>
- <app-management-permission-item id="microphone"
- class="subpermission-row" icon="cr:mic"
- permission-label="$i18n{microphone}"
- permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC">
- </app-management-permission-item>
- <div class="subpermission-row separated-row clickable"
- on-click="onClickSiteSettingsButton_">
- <div class="header-text">$i18n{moreSettings}</div>
- <div class="permission-row-controls">
- <cr-icon-button class="native-settings-icon icon-external"
- tabindex="0">
- </cr-icon-button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script src="pwa_permission_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/pwa_permission_view.js b/chromium/chrome/browser/resources/app_management/pwa_permission_view.js
deleted file mode 100644
index bc475ed9085..00000000000
--- a/chromium/chrome/browser/resources/app_management/pwa_permission_view.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-pwa-permission-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * @private {App}
- */
- app_: Object,
-
- /**
- * @private {boolean}
- */
- listExpanded_: {
- type: Boolean,
- value: false,
- },
- },
-
- attached: function() {
- this.watch('app_', state => app_management.util.getSelectedApp(state));
- this.updateFromStore();
-
- this.listExpanded_ = false;
- },
-
- /**
- * @private
- */
- onClickSiteSettingsButton_: function() {
- app_management.BrowserProxy.getInstance().handler.openNativeSettings(
- this.app_.id);
- },
-
- /**
- * @private
- */
- toggleListExpanded_: function() {
- this.listExpanded_ = !this.listExpanded_;
- },
-
- /**
- * @param {App} app
- * @return {string}
- * @private
- */
- iconUrlFromId_: function(app) {
- return app_management.util.getAppIcon(app);
- },
-
- /**
- * @param {boolean} listExpanded
- * @return {string}
- * @private
- */
- getCollapsedIcon_: function(listExpanded) {
- return listExpanded ? 'cr:expand-less' : 'cr:expand-more';
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/reducers.html b/chromium/chrome/browser/resources/app_management/reducers.html
deleted file mode 100644
index 6eda04966b8..00000000000
--- a/chromium/chrome/browser/resources/app_management/reducers.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="reducers.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/reducers.js b/chromium/chrome/browser/resources/app_management/reducers.js
deleted file mode 100644
index 3b9de9038d9..00000000000
--- a/chromium/chrome/browser/resources/app_management/reducers.js
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2018 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 Module of functions which produce a new page state in response
- * to an action. Reducers (in the same sense as Array.prototype.reduce) must be
- * pure functions: they must not modify existing state objects, or make any API
- * calls.
- */
-
-cr.define('app_management', function() {
- const AppState = {};
-
- /**
- * @param {AppMap} apps
- * @param {Object} action
- * @return {AppMap}
- */
- AppState.addApp = function(apps, action) {
- assert(!apps[action.app.id]);
-
- const newAppEntry = {};
- newAppEntry[action.app.id] = action.app;
- return Object.assign({}, apps, newAppEntry);
- };
-
- /**
- * @param {AppMap} apps
- * @param {Object} action
- * @return {AppMap}
- */
- AppState.changeApp = function(apps, action) {
- assert(apps[action.app.id]);
-
- const changedAppEntry = {};
- changedAppEntry[action.app.id] = action.app;
- return Object.assign({}, apps, changedAppEntry);
- };
-
- /**
- * @param {AppMap} apps
- * @param {Object} action
- * @return {AppMap}
- */
- AppState.removeApp = function(apps, action) {
- if (!apps.hasOwnProperty(action.id)) {
- return apps;
- }
-
- delete apps[action.id];
- return Object.assign({}, apps);
- };
-
- /**
- * @param {AppMap} apps
- * @param {Object} action
- * @return {AppMap}
- */
- AppState.updateApps = function(apps, action) {
- switch (action.name) {
- case 'add-app':
- return AppState.addApp(apps, action);
- case 'change-app':
- return AppState.changeApp(apps, action);
- case 'remove-app':
- return AppState.removeApp(apps, action);
- default:
- return apps;
- }
- };
-
- const CurrentPageState = {};
-
- /**
- * @param {AppMap} apps
- * @param {Object} action
- * @return {Page}
- */
- CurrentPageState.changePage = function(apps, action) {
- if (action.pageType === PageType.DETAIL && apps[action.id]) {
- return {
- pageType: PageType.DETAIL,
- selectedAppId: action.id,
- };
- } else if (action.pageType === PageType.NOTIFICATIONS) {
- return {
- pageType: PageType.NOTIFICATIONS,
- selectedAppId: null,
- };
- } else {
- return {
- pageType: PageType.MAIN,
- selectedAppId: null,
- };
- }
- };
-
- /**
- * @param {Page} currentPage
- * @param {Object} action
- * @return {Page}
- */
- CurrentPageState.removeApp = function(currentPage, action) {
- if (currentPage.pageType === PageType.DETAIL &&
- currentPage.selectedAppId === action.id) {
- return {
- pageType: PageType.MAIN,
- selectedAppId: null,
- };
- } else {
- return currentPage;
- }
- };
-
- /**
- * @param {AppMap} apps
- * @param {Page} currentPage
- * @param {Object} action
- * @return {Page}
- */
- CurrentPageState.updateCurrentPage = function(apps, currentPage, action) {
- switch (action.name) {
- case 'change-page':
- return CurrentPageState.changePage(apps, action);
- case 'remove-app':
- return CurrentPageState.removeApp(currentPage, action);
- default:
- return currentPage;
- }
- };
-
- const SearchState = {};
-
- /**
- * @param {AppMap} apps
- * @param {SearchState} search
- * @param {Object} action
- * @return {SearchState}
- */
- SearchState.startSearch = function(apps, search, action) {
- if (action.term === search.term) {
- return search;
- }
-
- const results = [];
-
- for (const app of Object.values(apps)) {
- if (app.title.toLowerCase().includes(action.term.toLowerCase())) {
- results.push(app);
- }
- }
-
- results.sort(
- (a, b) => app_management.util.alphabeticalSort(
- assert(a.title), assert(b.title)));
-
- return /** @type {SearchState} */ (Object.assign({}, search, {
- term: action.term,
- results: results,
- }));
- };
-
- /** @return {SearchState} */
- SearchState.clearSearch = function() {
- return {
- term: null,
- results: null,
- };
- };
-
- /**
- * @param {AppMap} apps
- * @param {SearchState} search
- * @param {Object} action
- * @return {SearchState}
- */
- SearchState.updateSearch = function(apps, search, action) {
- switch (action.name) {
- case 'start-search':
- return SearchState.startSearch(apps, search, action);
- case 'clear-search':
- case 'change-page':
- return SearchState.clearSearch();
- default:
- return search;
- }
- };
-
- const NotificationsState = {};
-
- /**
- * @param {NotificationsState} notifications
- * @param {Object} action
- * @return {NotificationsState}
- */
- NotificationsState.addApp = function(notifications, action) {
- let {allowedIds, blockedIds} = notifications;
- const allowed = app_management.util.notificationsAllowed(action.app);
-
- if (allowed === OptionalBool.kUnknown) {
- return {allowedIds, blockedIds};
- }
-
- if (allowed === OptionalBool.kTrue) {
- allowedIds = app_management.util.addIfNeeded(allowedIds, action.app.id);
- } else {
- blockedIds = app_management.util.addIfNeeded(blockedIds, action.app.id);
- }
-
- return {allowedIds, blockedIds};
- };
-
- /**
- * @param {NotificationsState} notifications
- * @param {Object} action
- * @return {NotificationsState}
- */
- NotificationsState.changeApp = function(notifications, action) {
- let {allowedIds, blockedIds} = notifications;
- const allowed = app_management.util.notificationsAllowed(action.app);
- const id = action.app.id;
-
- if (allowed === OptionalBool.kUnknown) {
- assert(!blockedIds.has(id) && !allowedIds.has(id));
- return {allowedIds, blockedIds};
- }
-
- if (allowed === OptionalBool.kTrue) {
- allowedIds = app_management.util.addIfNeeded(allowedIds, id);
- blockedIds = app_management.util.removeIfNeeded(blockedIds, id);
- } else {
- allowedIds = app_management.util.removeIfNeeded(allowedIds, id);
- blockedIds = app_management.util.addIfNeeded(blockedIds, id);
- }
-
- return {allowedIds, blockedIds};
- };
-
- /**
- * @param {NotificationsState} notifications
- * @param {Object} action
- * @return {NotificationsState}
- */
- NotificationsState.removeApp = function(notifications, action) {
- let {allowedIds, blockedIds} = notifications;
- allowedIds = app_management.util.removeIfNeeded(allowedIds, action.id);
- blockedIds = app_management.util.removeIfNeeded(blockedIds, action.id);
-
- return {allowedIds, blockedIds};
- };
-
- /**
- * @param {NotificationsState} notifications
- * @param {Object} action
- * @return {NotificationsState}
- */
- NotificationsState.updateNotifications = function(notifications, action) {
- switch (action.name) {
- case 'add-app':
- return NotificationsState.addApp(notifications, action);
- case 'change-app':
- return NotificationsState.changeApp(notifications, action);
- case 'remove-app':
- return NotificationsState.removeApp(notifications, action);
- default:
- return notifications;
- }
- };
-
- const ArcSupported = {};
-
- /**
- * @param {boolean} arcSupported
- * @param {Object} action
- * @return {boolean}
- */
- ArcSupported.updateArcSupported = function(arcSupported, action) {
- switch (action.name) {
- case 'update-arc-supported':
- return action.value;
- default:
- return arcSupported;
- }
- };
-
- /**
- * Root reducer for the App Management page. This is called by the store in
- * response to an action, and the return value is used to update the UI.
- * @param {!AppManagementPageState} state
- * @param {Object} action
- * @return {!AppManagementPageState}
- */
- function reduceAction(state, action) {
- return {
- apps: AppState.updateApps(state.apps, action),
- currentPage: CurrentPageState.updateCurrentPage(
- state.apps, state.currentPage, action),
- arcSupported: ArcSupported.updateArcSupported(state.arcSupported, action),
- search: SearchState.updateSearch(state.apps, state.search, action),
- notifications:
- NotificationsState.updateNotifications(state.notifications, action),
- };
- }
-
- return {
- reduceAction: reduceAction,
- AppState: AppState,
- CurrentPageState: CurrentPageState,
- ArcSupported: ArcSupported,
- NotificationsState: NotificationsState,
- SearchState: SearchState,
- };
-});
diff --git a/chromium/chrome/browser/resources/app_management/router.html b/chromium/chrome/browser/resources/app_management/router.html
deleted file mode 100644
index bbe2548c83a..00000000000
--- a/chromium/chrome/browser/resources/app_management/router.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="actions.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="constants.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-location.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-query-params.html">
-
-<dom-module id="app-management-router">
- <template>
- <iron-location id="iron-location" query="{{urlQuery_}}" path="{{path_}}">
- </iron-location>
- <iron-query-params params-string="{{query_}}"
- params-object="{{queryParams_}}"></iron-query-params>
- </template>
- <script src="router.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/router.js b/chromium/chrome/browser/resources/app_management/router.js
deleted file mode 100644
index f0f96baff33..00000000000
--- a/chromium/chrome/browser/resources/app_management/router.js
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2018 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.
-
-Polymer({
- is: 'app-management-router',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /** @private {string} */
- path_: String,
-
- /** @private {Object} */
- queryParams_: Object,
-
- /** @private {string} */
- query_: {
- type: String,
- observer: 'onQueryChanged_',
- },
-
- /** @private {string} */
- urlQuery_: {
- type: String,
- observer: 'onUrlQueryChanged_',
- },
-
- /** @private */
- searchTerm_: {
- type: String,
- value: '',
- },
-
- /** @private {PageType} */
- currentPageType_: {
- type: Number,
- },
-
- /** @private {?string} */
- selectedAppId_: {
- type: String,
- },
- },
-
- urlParsed_: false,
-
- observers: [
- 'onUrlChanged_(path_, queryParams_)',
- 'onStateChanged_(currentPageType_, selectedAppId_, searchTerm_)',
- ],
-
- attached: function() {
- this.watch('currentPageType_', (state) => {
- return state.currentPage.pageType;
- });
- this.watch('selectedAppId_', (state) => {
- return state.currentPage.selectedAppId;
- });
- this.watch('searchTerm_', (state) => {
- return state.search.term;
- });
- this.updateFromStore();
- },
-
- /**
- * @param {?string} current Current value of the query.
- * @param {?string} previous Previous value of the query.
- * @private
- */
- onQueryChanged_: function(current, previous) {
- if (previous !== undefined) {
- this.urlQuery_ = this.query_;
- }
- },
-
- /** @private */
- onUrlQueryChanged_: function() {
- this.query_ = this.urlQuery_;
- },
-
- /** @private */
- onStateChanged_: function() {
- if (!this.urlParsed_) {
- return;
- }
- this.debounce('publishUrl', this.publishUrl_);
- },
-
- /** @private */
- publishUrl_: function() {
- // Disable pushing urls into the history stack, so that we only push one
- // state.
- this.$['iron-location'].dwellTime = Infinity;
- this.publishQueryParams_();
- // Re-enable pushing urls into the history stack.
- this.$['iron-location'].dwellTime = 0;
- this.publishPath_();
- },
-
- /** @private */
- publishQueryParams_: function() {
- const newQueryParams = Object.assign({}, this.queryParams_);
-
- newQueryParams.q = this.searchTerm_ || undefined;
- newQueryParams.id = this.selectedAppId_ || undefined;
-
- // Can't update |this.queryParams_| every time since assigning a new object
- // to it triggers a state change which causes the URL to change, which
- // recurses into a loop. JSON.stringify is used here to compare objects as
- // it is always going to be a key value (string) pair and will serialize
- // correctly.
- if (JSON.stringify(newQueryParams) !== JSON.stringify(this.queryParams_)) {
- this.queryParams_ = newQueryParams;
- }
- },
-
- /** @private */
- publishPath_: function() {
- let path = '';
- if (this.currentPageType_ === PageType.DETAIL) {
- path = 'detail';
- } else if (this.currentPageType_ === PageType.NOTIFICATIONS) {
- path = 'notifications';
- }
- this.path_ = '/' + path;
- },
-
- /** @private */
- onUrlChanged_: function() {
- this.debounce('parseUrl', this.parseUrl_);
- },
-
- /** @private */
- parseUrl_: function() {
- const newId = this.queryParams_.id;
- const searchTerm = this.queryParams_.q;
-
- const pageFromUrl = this.path_.substr(1).split('/')[0];
- let newPage = PageType.MAIN;
- if (pageFromUrl === 'detail') {
- newPage = PageType.DETAIL;
- } else if (pageFromUrl === 'notifications') {
- newPage = PageType.NOTIFICATIONS;
- } else {
- newPage = PageType.MAIN;
- }
-
- if (newPage === PageType.DETAIL) {
- this.dispatch(app_management.actions.changePage(PageType.DETAIL, newId));
- } else {
- this.dispatch(app_management.actions.changePage(newPage));
- }
-
- if (searchTerm) {
- this.dispatch(app_management.actions.setSearchTerm(searchTerm));
- }
- this.urlParsed_ = true;
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/search_view.html b/chromium/chrome/browser/resources/app_management/search_view.html
deleted file mode 100644
index c2d94266af7..00000000000
--- a/chromium/chrome/browser/resources/app_management/search_view.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="app_item.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
-
-<dom-module id="app-management-search-view">
- <template>
- <style include="app-management-shared-css">
- #centered-message {
- align-items: center;
- color: #6e6e6e;
- cursor: default;
- display: flex;
- font-size: 14px;
- font-weight: 500;
- height: 100%;
- justify-content: center;
- user-select: none;
- white-space: nowrap;
- }
-
- .app-management-item-arrow {
- margin-inline-end: 8px;
- padding: 12px;
- }
- </style>
- <div class="card-container" hidden$="[[isEmptyList_(apps_)]]">
- <template is="dom-repeat" items="[[apps_]]">
- <app-management-app-item app="[[item]]">
- <cr-icon-button slot="right-content"
- class="subpage-arrow app-management-item-arrow" actionable>
- </cr-icon-button>
- </app-management-app-item>
- </template>
- </div>
- <div id="centered-message"
- hidden$="[[!isEmptyList_(apps_)]]">
- $i18n{noSearchResults}
- </div>
- </template>
- <script src="search_view.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/search_view.js b/chromium/chrome/browser/resources/app_management/search_view.js
deleted file mode 100644
index b149e94e119..00000000000
--- a/chromium/chrome/browser/resources/app_management/search_view.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 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.
-Polymer({
- is: 'app-management-search-view',
-
- behaviors: [
- app_management.StoreClient,
- ],
-
- properties: {
- /**
- * List of apps returned from search results.
- * @private {Array<App>}
- */
- apps_: {
- type: Array,
- value: () => [],
- },
- },
-
- attached: function() {
- this.watch('apps_', (state) => {
- return state.search.results;
- });
- },
-
- /**
- * Check whether there is search results.
- * @param {Array<App>} apps
- * @return {boolean}
- * @private
- */
- isEmptyList_: function(apps) {
- if (!apps) {
- return true;
- }
- return apps.length === 0;
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/shared_style.html b/chromium/chrome/browser/resources/app_management/shared_style.html
deleted file mode 100644
index 57215df600e..00000000000
--- a/chromium/chrome/browser/resources/app_management/shared_style.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<link rel="import" href="shared_vars.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-
-<!-- Common styles for App Management. -->
-<dom-module id="app-management-shared-css">
- <template>
- <style include="cr-shared-style">
- .card-container {
- @apply --cr-card-elevation;
- background-color: #fff;
- border-radius: var(--cr-card-border-radius);
- display: flex;
- flex-direction: column;
- margin: 24px auto;
- max-width: var(--card-max-width);
- min-width: var(--card-min-width);
- }
-
- .separated-row {
- align-items: center;
- display: inline-flex;
- justify-content: space-between;
- }
-
- .card-row {
- border-top: var(--card-separator);
- padding: 0 24px;
- }
-
- .permission-card-row {
- border-top: var(--card-separator);
- padding: 0 24px;
- }
-
- .clickable {
- cursor: pointer;
- }
-
- .permission-card-row:first-child {
- border-style: none;
- }
-
- .header-text {
- color: var(--header-text-color);
- font-weight: var(--header-font-weight);
- }
-
- .permission-row-controls {
- align-items: center;
- display: inline-flex;
- }
-
- .permission-list {
- display: flex;
- flex-direction: column;
- }
-
- .permission-list > * {
- flex: 0 0 var(--permission-list-item-height);
- }
-
- .native-settings-icon {
- display: flex;
- margin-inline-start: 0;
- }
-
- .subpermission-row {
- height: 48px;
- }
-
- .subpermission-list {
- align-items: stretch;
- display: flex;
- flex-direction: column;
- padding: 8px 0;
- }
-
- .secondary-text {
- color: var(--secondary-text-color);
- font-weight: var(--secondary-font-weight);
- }
-
- .expand-button {
- height: 36px;
- margin-inline-end: 12px;
- width: 36px;
- }
-
- .horizontal-align {
- align-items: center;
- display: flex;
- }
-
- .expander-list-row {
- align-items: center;
- border-top: var(--card-separator);
- color: var(--secondary-text-color);
- display: flex;
- height: 50px;
- justify-content: space-between;
- padding-inline-end: 8px;
- padding-inline-start: 24px;
- }
-
- .page-title {
- flex: 1;
- font-size: 16px;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- </style>
- </template>
diff --git a/chromium/chrome/browser/resources/app_management/shared_vars.html b/chromium/chrome/browser/resources/app_management/shared_vars.html
deleted file mode 100644
index d42cace22d1..00000000000
--- a/chromium/chrome/browser/resources/app_management/shared_vars.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-
-<custom-style>
-<style>
- html {
- --app-management-font-size: 13px;
- --app-management-line-height: 1.54; /* 20px */
- --card-max-width: 676px;
- --card-min-width: 550px;
- --card-separator: 1px solid rgba(0, 0, 0, 0.12);
- --control-separator-color: rgb(218, 220, 224);
- --expanded-permission-row-height: 48px;
- --header-font-weight: 500;
- --header-text-color: #5A5A5A;
- --permission-icon-color: #757575;
- --permission-icon-padding: 12px;
- --permission-list-item-height: 64px;
- --primary-text-color: rgba(0, 0, 0, 0.87);
- --row-item-icon-padding: 12px;
- --secondary-font-weight: 400;
- --secondary-text-color: rgba(0, 0, 0, 0.54);
- }
-</style>
-</custom-style>
diff --git a/chromium/chrome/browser/resources/app_management/store.html b/chromium/chrome/browser/resources/app_management/store.html
deleted file mode 100644
index dd30152b65f..00000000000
--- a/chromium/chrome/browser/resources/app_management/store.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/cr/ui/store.html">
-<link rel="import" href="reducers.html">
-<link rel="import" href="util.html">
-
-<script src="store.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/store.js b/chromium/chrome/browser/resources/app_management/store.js
deleted file mode 100644
index 9790d51dae6..00000000000
--- a/chromium/chrome/browser/resources/app_management/store.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 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 singleton datastore for the App Management page. Page state
- * is publicly readable, but can only be modified by dispatching an Action to
- * the store.
- */
-
-cr.define('app_management', function() {
- class Store extends cr.ui.Store {
- constructor() {
- super(
- app_management.util.createEmptyState(), app_management.reduceAction);
- }
- }
-
- cr.addSingletonGetter(Store);
-
- return {
- Store: Store,
- };
-});
diff --git a/chromium/chrome/browser/resources/app_management/store_client.html b/chromium/chrome/browser/resources/app_management/store_client.html
deleted file mode 100644
index e7d72ccfd35..00000000000
--- a/chromium/chrome/browser/resources/app_management/store_client.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/cr/ui/store_client.html">
-<link rel="import" href="store.html">
-
-<script src="store_client.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/store_client.js b/chromium/chrome/browser/resources/app_management/store_client.js
deleted file mode 100644
index 0469381c537..00000000000
--- a/chromium/chrome/browser/resources/app_management/store_client.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 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 Defines StoreClient, a Polymer behavior to tie a front-end
- * element to back-end data from the store.
- */
-
-cr.define('app_management', function() {
- /**
- * @polymerBehavior
- */
- const AppManagementStoreClientImpl = {
- /**
- * @param {string} localProperty
- * @param {function(!AppManagementPageState)} valueGetter
- */
- watch: function(localProperty, valueGetter) {
- this.watch_(localProperty, valueGetter);
- },
-
- /**
- * @return {AppManagementPageState}
- */
- getState: function() {
- return this.getStore().data;
- },
-
- /**
- * @return {cr.ui.Store<AppManagementPageState>}
- */
- getStore: function() {
- return app_management.Store.getInstance();
- },
- };
-
- /**
- * @polymerBehavior
- * @implements {cr.ui.StoreObserver}
- */
- const StoreClient = [cr.ui.StoreClient, AppManagementStoreClientImpl];
-
- return {
- AppManagementStoreClientImpl: AppManagementStoreClientImpl,
- StoreClient: StoreClient,
- };
-});
diff --git a/chromium/chrome/browser/resources/app_management/toggle_row.html b/chromium/chrome/browser/resources/app_management/toggle_row.html
deleted file mode 100644
index 8e2ccf129b8..00000000000
--- a/chromium/chrome/browser/resources/app_management/toggle_row.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="browser_proxy.html">
-<link rel="import" href="shared_style.html">
-<link rel="import" href="store_client.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-
-<dom-module id="app-management-toggle-row">
- <template>
- <style include="app-management-shared-css">
- :host {
- align-items: center;
- display: flex;
- flex: 1;
- justify-content: space-between;
- }
-
- #icon {
- padding-inline-end: var(--row-item-icon-padding);
- }
-
- #policy-indicator {
- fill: var(--google-grey-refresh-700);
- padding-inline-end: 12px;
- }
- </style>
-
- <div id="left-content" class="horizontal-align">
- <template is="dom-if" if="[[icon_]]">
- <iron-icon id="icon" icon="[[icon_]]"></iron-icon>
- </template>
- <div id="label">[[label_]]</div>
- </div>
- <div id="right-content" class="horizontal-align">
- <iron-icon id="policy-indicator"
- icon="cr:domain"
- tabindex="0"
- aria-describedby="tooltip"
- hidden$="[[!managed_]]">
- </iron-icon>
- <paper-tooltip id="tooltip"
- for="policy-indicator"
- position="top"
- fit-to-visible-bounds>
- [[policyLabel_]]
- </paper-tooltip>
- <cr-toggle id="toggle"
- checked="[[value_]]"
- disabled$="[[managed_]]">
- </cr-toggle>
- </div>
- </template>
- <script src="toggle_row.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/app_management/toggle_row.js b/chromium/chrome/browser/resources/app_management/toggle_row.js
deleted file mode 100644
index 16aff0bb109..00000000000
--- a/chromium/chrome/browser/resources/app_management/toggle_row.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.
-Polymer({
- is: 'app-management-toggle-row',
-
- properties: {
- /**
- * @type {string}
- * @private
- */
- icon_: String,
- /**
- * @type {string}
- * @private
- */
- label_: String,
- /**
- * @type {boolean}
- * @private
- */
- managed_: {type: Boolean, value: false, reflectToAttribute: true},
- /**
- * @type {string}
- * @private
- */
- policyLabel_: String,
- /**
- * @type {boolean}
- * @private
- */
- value_: {type: Boolean, value: false, reflectToAttribute: true},
- },
-});
diff --git a/chromium/chrome/browser/resources/app_management/types.js b/chromium/chrome/browser/resources/app_management/types.js
deleted file mode 100644
index 725836f9596..00000000000
--- a/chromium/chrome/browser/resources/app_management/types.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 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 Closure typedefs for App Management.
- */
-
-/**
- * @typedef {appManagement.mojom.App}
- */
-let App;
-
-/**
- * @typedef {appManagement.mojom.ExtensionAppPermissionMessage}
- */
-let ExtensionAppPermissionMessage;
-
-/**
- * @typedef {apps.mojom.Permission}
- */
-let Permission;
-
-/**
- * Maps app ids to Apps.
- * @typedef {!Object<string, App>}
- */
-let AppMap;
-
-/**
- * @typedef {{
- * pageType: PageType,
- * selectedAppId: ?string,
- * }}
- */
-let Page;
-
-/**
- * @typedef {{
- * term: ?string,
- * results: ?Array<App>,
- * }}
- */
-let SearchState;
-
-/**
- * @typedef {{
- * allowedIds: !Set<string>,
- * blockedIds: !Set<string>,
- * }}
- */
-let NotificationsState;
-
-/**
- * @typedef {{
- * apps: !AppMap,
- * currentPage: !Page,
- * arcSupported: boolean,
- * search: !SearchState,
- * notifications: !NotificationsState,
- * }}
- */
-let AppManagementPageState;
diff --git a/chromium/chrome/browser/resources/app_management/util.html b/chromium/chrome/browser/resources/app_management/util.html
deleted file mode 100644
index d521fc5bd60..00000000000
--- a/chromium/chrome/browser/resources/app_management/util.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="util.js"></script>
diff --git a/chromium/chrome/browser/resources/app_management/util.js b/chromium/chrome/browser/resources/app_management/util.js
deleted file mode 100644
index 1e94d7cce9a..00000000000
--- a/chromium/chrome/browser/resources/app_management/util.js
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2018 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 Utility functions for the App Management page.
- */
-
-cr.define('app_management.util', function() {
- /**
- * @return {!AppManagementPageState}
- */
- function createEmptyState() {
- return {
- apps: {},
- currentPage: {
- pageType: PageType.MAIN,
- selectedAppId: null,
- },
- arcSupported: false,
- search: {
- term: null,
- results: null,
- },
- notifications: {
- allowedIds: new Set(),
- blockedIds: new Set(),
- },
- };
- }
-
- /**
- * @param {!Array<App>} apps
- * @return {!AppManagementPageState}
- */
- function createInitialState(apps) {
- const initialState = createEmptyState();
-
- initialState.arcSupported =
- loadTimeData.valueExists('isSupportedArcVersion') &&
- loadTimeData.getBoolean('isSupportedArcVersion');
-
- for (const app of apps) {
- initialState.apps[app.id] = app;
-
- const allowed = notificationsAllowed(app);
-
- if (allowed === OptionalBool.kUnknown) {
- continue;
- }
-
- if (allowed === OptionalBool.kTrue) {
- initialState.notifications.allowedIds.add(app.id);
- } else {
- initialState.notifications.blockedIds.add(app.id);
- }
- }
-
- return initialState;
- }
-
- /**
- * @param {number} permissionId
- * @param {!PermissionValueType} valueType
- * @param {number} value
- * @param {boolean} isManaged
- * @return {!Permission}
- */
- function createPermission(permissionId, valueType, value, isManaged) {
- return {
- permissionId,
- valueType,
- value,
- isManaged,
- };
- }
-
- /**
- * @param {App} app
- * @return {string}
- */
- function getAppIcon(app) {
- return `chrome://app-icon/${app.id}/128`;
- }
-
- /**
- * If the given value is not in the set, returns a new set with the value
- * added, otherwise returns the old set.
- * @template T
- * @param {!Set<T>} set
- * @param {T} value
- * @return {!Set<T>}
- */
- function addIfNeeded(set, value) {
- if (!set.has(value)) {
- set = new Set(set);
- set.add(value);
- }
- return set;
- }
-
- /**
- * If the given value is in the set, returns a new set without the value,
- * otherwise returns the old set.
- * @template T
- * @param {!Set<T>} set
- * @param {T} value
- * @return {!Set<T>}
- */
- function removeIfNeeded(set, value) {
- if (set.has(value)) {
- set = new Set(set);
- set.delete(value);
- }
- return set;
- }
-
- /**
- * This function determines whether the given app should be treated by the
- * notifications view as having notifications allowed or blocked, or not
- * having a notifications permission at all.
- *
- * There are three possible cases:
- * - kUnknown is returned if the given app does not have a notifications
- * permission, due to how permissions work for its AppType.
- * - kTrue is returned if the notifications permission of the app is allowed.
- * - kFalse is returned if the notifications permission of the app is
- * - blocked, or set to ask in the case of a tristate permission.
- *
- * @param {App} app
- * @return {OptionalBool}
- */
- function notificationsAllowed(app) {
- const permissionType = notificationsPermissionType(app);
-
- if (!permissionType) {
- return OptionalBool.kUnknown;
- }
-
- if (getPermissionValueBool(app, permissionType)) {
- return OptionalBool.kTrue;
- } else {
- return OptionalBool.kFalse;
- }
- }
-
- /**
- * Returns a string corresponding to the notifications value of the
- * appropriate permission type enum, based on the type of the app.
- * Returns null if the app type doesn't have a notifications permission.
- * @param {App} app
- * @return {?string}
- */
- function notificationsPermissionType(app) {
- switch (app.type) {
- case AppType.kWeb:
- return 'CONTENT_SETTINGS_TYPE_NOTIFICATIONS';
- // TODO(rekanorman): Add another case once notifications permissions
- // are implemented for ARC.
- default:
- return null;
- }
- }
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {boolean}
- */
- function getPermissionValueBool(app, permissionType) {
- const permission = getPermission(app, permissionType);
- assert(permission);
-
- switch (permission.valueType) {
- case PermissionValueType.kBool:
- return permission.value === Bool.kTrue;
- case PermissionValueType.kTriState:
- return permission.value === TriState.kAllow;
- default:
- assertNotReached();
- }
- }
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {Permission}
- */
- function getPermission(app, permissionType) {
- return app.permissions[permissionTypeHandle(app, permissionType)];
- }
-
- /**
- * @param {App} app
- * @param {string} permissionType
- * @return {number}
- */
- function permissionTypeHandle(app, permissionType) {
- switch (app.type) {
- case AppType.kWeb:
- return PwaPermissionType[permissionType];
- case AppType.kArc:
- return ArcPermissionType[permissionType];
- default:
- assertNotReached();
- }
- }
-
- /**
- * @param {AppManagementPageState} state
- * @return {?App}
- */
- function getSelectedApp(state) {
- const selectedAppId = state.currentPage.selectedAppId;
- return selectedAppId ? state.apps[selectedAppId] : null;
- }
-
- /**
- * A comparator function to sort strings alphabetically.
- *
- * @param {string} a
- * @param {string} b
- */
- function alphabeticalSort(a, b) {
- return a.localeCompare(b);
- }
-
- /**
- * Toggles an OptionalBool
- *
- * @param {OptionalBool} bool
- * @return {OptionalBool}
- */
- function toggleOptionalBool(bool) {
- switch (bool) {
- case OptionalBool.kFalse:
- return OptionalBool.kTrue;
- case OptionalBool.kTrue:
- return OptionalBool.kFalse;
- default:
- assertNotReached();
- }
- }
-
- return {
- addIfNeeded: addIfNeeded,
- alphabeticalSort: alphabeticalSort,
- createEmptyState: createEmptyState,
- createInitialState: createInitialState,
- createPermission: createPermission,
- getAppIcon: getAppIcon,
- getPermission: getPermission,
- getPermissionValueBool: getPermissionValueBool,
- getSelectedApp: getSelectedApp,
- notificationsAllowed: notificationsAllowed,
- notificationsPermissionType: notificationsPermissionType,
- permissionTypeHandle: permissionTypeHandle,
- removeIfNeeded: removeIfNeeded,
- toggleOptionalBool: toggleOptionalBool,
- };
-});
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn b/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
index 88abbb1f3ee..7ab5c808a39 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
+++ b/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/grit_rule.gni")
js_type_check("closure_compile") {
deps = [
@@ -41,3 +42,25 @@ js_library("bluetooth_internals") {
"//ui/webui/resources/js/cr/ui/page_manager:page_manager",
]
}
+
+grit("resources") {
+ source = "resources.grd"
+
+ # The .grd contains references to generated files.
+ source_is_generated = true
+ outputs = [
+ "grit/bluetooth_internals_resources.h",
+ "grit/bluetooth_internals_resources_map.h",
+ "grit/bluetooth_internals_resources_map.cc",
+ "bluetooth_internals_resources.pak",
+ ]
+ output_dir = "$root_gen_dir/chrome"
+ depfile_dir = target_gen_dir
+ grit_flags = [
+ "-E",
+ "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+ ]
+ deps = [
+ "//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_js",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
index 918c700cce3..0da84a773fe 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -7,12 +7,12 @@
* chrome://bluetooth-internals/.
*/
cr.define('adapter_broker', function() {
- /** @typedef {bluetooth.mojom.AdapterProxy} */
- let AdapterProxy;
- /** @typedef {bluetooth.mojom.DeviceProxy} */
- let DeviceProxy;
- /** @typedef {bluetooth.mojom.DiscoverySessionProxy} */
- let DiscoverySessionProxy;
+ /** @typedef {bluetooth.mojom.AdapterRemote} */
+ let AdapterRemote;
+ /** @typedef {bluetooth.mojom.DeviceRemote} */
+ let DeviceRemote;
+ /** @typedef {bluetooth.mojom.DiscoverySessionRemote} */
+ let DiscoverySessionRemote;
/**
* Enum of adapter property names. Used for adapterchanged events.
@@ -29,18 +29,20 @@ cr.define('adapter_broker', function() {
* The proxy class of an adapter and router of adapter events.
* Exposes an EventTarget interface that allows other object to subscribe to
* to specific AdapterClient events.
- * Provides proxy access to Adapter functions. Converts parameters to Mojo
+ * Provides remote access to Adapter functions. Converts parameters to Mojo
* handles and back when necessary.
*
* @implements {bluetooth.mojom.AdapterClientInterface}
*/
class AdapterBroker extends cr.EventTarget {
- /** @param {!AdapterProxy} adapter */
+ /** @param {!AdapterRemote} adapter */
constructor(adapter) {
super();
- this.adapterClient_ = new bluetooth.mojom.AdapterClient(this);
+ this.adapterClientReceiver_ =
+ new bluetooth.mojom.AdapterClientReceiver(this);
this.adapter_ = adapter;
- this.adapter_.setClient(this.adapterClient_.$.createProxy());
+ this.adapter_.setClient(
+ this.adapterClientReceiver_.$.bindNewPipeAndPassRemote());
}
presentChanged(present) {
@@ -135,7 +137,7 @@ cr.define('adapter_broker', function() {
/**
* Requests the adapter to start a new discovery session.
- * @return {!Promise<!bluetooth.mojom.DiscoverySessionProxy>}
+ * @return {!Promise<!bluetooth.mojom.DiscoverySessionRemote>}
*/
startDiscoverySession() {
return this.adapter_.startDiscoverySession().then(function(response) {
@@ -161,7 +163,7 @@ cr.define('adapter_broker', function() {
}
const bluetoothInternalsHandler =
- mojom.BluetoothInternalsHandler.getProxy();
+ mojom.BluetoothInternalsHandler.getRemote();
// Get an Adapter service.
return bluetoothInternalsHandler.getAdapter().then(function(response) {
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
index 12521d2de95..de4b6d0a4d9 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
@@ -30,7 +30,7 @@ cr.define('bluetooth_internals', function() {
/** @type {devices_page.DevicesPage} */
let devicesPage = null;
- /** @type {bluetooth.mojom.DiscoverySessionProxy} */
+ /** @type {bluetooth.mojom.DiscoverySessionRemote} */
let discoverySession = null;
/** @type {boolean} */
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/device_broker.js b/chromium/chrome/browser/resources/bluetooth_internals/device_broker.js
index e166d114d56..3c417d9f7ce 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/device_broker.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/device_broker.js
@@ -4,15 +4,15 @@
/**
* Javascript for device_broker, served from chrome://bluetooth-internals/.
- * Provides a single source to access DeviceProxys. DeviceProxys are cached for
+ * Provides a single source to access DeviceRemotes. DeviceRemotes are cached
* for repeated use. Multiple connection requests will result in the same
- * DeviceProxy being shared among all requesters.
+ * DeviceRemote being shared among all requesters.
*/
// Expose for testing.
/**
* @type {?Map<string,
- * !bluetooth.mojom.DeviceProxy|!Promise<!bluetooth.mojom.DeviceProxy>>}
+ * !bluetooth.mojom.DeviceRemote|!Promise<!bluetooth.mojom.DeviceRemote>>}
*/
let connectedDevices = null;
@@ -22,10 +22,10 @@ cr.define('device_broker', function() {
/**
* Creates a GATT connection to the device with |address|. If a connection to
* the device already exists, the promise is resolved with the existing
- * DeviceProxy. If a connection is in progress, the promise resolves when
+ * DeviceRemote. If a connection is in progress, the promise resolves when
* the existing connection request promise is fulfilled.
* @param {string} address
- * @return {!Promise<!bluetooth.mojom.DeviceProxy>}
+ * @return {!Promise<!bluetooth.mojom.DeviceRemote>}
*/
function connectToDevice(address) {
const deviceOrPromise = connectedDevices.get(address) || null;
@@ -33,7 +33,7 @@ cr.define('device_broker', function() {
return Promise.resolve(deviceOrPromise);
}
- const promise = /** @type {!Promise<!bluetooth.mojom.DeviceProxy>} */ (
+ const promise = /** @type {!Promise<!bluetooth.mojom.DeviceRemote>} */ (
adapter_broker.getAdapterBroker()
.then(function(adapterBroker) {
return adapterBroker.connectToDevice(address);
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/device_details_page.js b/chromium/chrome/browser/resources/bluetooth_internals/device_details_page.js
index 0a2f977ed75..876d45e68ec 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/device_details_page.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/device_details_page.js
@@ -46,8 +46,8 @@ cr.define('device_details_page', function() {
/** @type {?Array<bluetooth.mojom.ServiceInfo>} */
this.services = null;
- /** @private {?bluetooth.mojom.DeviceProxy} */
- this.deviceProxy_ = null;
+ /** @private {?bluetooth.mojom.DeviceRemote} */
+ this.device_ = null;
/** @private {!object_fieldset.ObjectFieldSet} */
this.deviceFieldSet_ = new object_fieldset.ObjectFieldSet();
@@ -81,7 +81,7 @@ cr.define('device_details_page', function() {
this.connectBtn_ = this.pageDiv.querySelector('.disconnect');
this.connectBtn_.addEventListener('click', function() {
- this.deviceProxy_ !== null ? this.disconnect() : this.connect();
+ this.device_ !== null ? this.disconnect() : this.connect();
}.bind(this));
this.redraw();
@@ -97,14 +97,14 @@ cr.define('device_details_page', function() {
device_collection.ConnectionStatus.CONNECTING);
device_broker.connectToDevice(this.deviceInfo.address)
- .then(function(deviceProxy) {
- this.deviceProxy_ = deviceProxy;
+ .then(function(device) {
+ this.device_ = device;
this.updateConnectionStatus_(
device_collection.ConnectionStatus.CONNECTED);
// Fetch services asynchronously.
- return this.deviceProxy_.getServices();
+ return this.device_.getServices();
}.bind(this))
.then(function(response) {
this.services = response.services;
@@ -114,10 +114,10 @@ cr.define('device_details_page', function() {
}.bind(this))
.catch(function(error) {
// If a connection error occurs while fetching the services, the
- // DeviceProxy reference must be removed.
- if (this.deviceProxy_) {
- this.deviceProxy_.disconnect();
- this.deviceProxy_ = null;
+ // DeviceRemote reference must be removed.
+ if (this.device_) {
+ this.device_.disconnect();
+ this.device_ = null;
}
Snackbar.show(
@@ -131,12 +131,12 @@ cr.define('device_details_page', function() {
/** Disconnects the page from the Bluetooth device. */
disconnect() {
- if (!this.deviceProxy_) {
+ if (!this.device_) {
return;
}
- this.deviceProxy_.disconnect();
- this.deviceProxy_ = null;
+ this.device_.disconnect();
+ this.device_ = null;
this.updateConnectionStatus_(
device_collection.ConnectionStatus.DISCONNECTED);
}
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/resources.grd b/chromium/chrome/browser/resources/bluetooth_internals/resources.grd
new file mode 100644
index 00000000000..786dc15be70
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/resources.grd
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0"
+ current_release="1"
+ output_all_resource_defines="false">
+ <outputs>
+ <output filename="grit/bluetooth_internals_resources.h"
+ type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="grit/bluetooth_internals_resources_map.cc"
+ type="resource_file_map_source" />
+ <output filename="grit/bluetooth_internals_resources_map.h"
+ type="resource_map_header" />
+ <output filename="bluetooth_internals_resources.pak"
+ type="data_package" />
+ </outputs>
+ <release seq="1">
+ <includes>
+ <include name="IDR_BLUETOOTH_INTERNALS_ADAPTER_BROKER_JS"
+ file="adapter_broker.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_ADAPTER_MOJO_JS"
+ file="${root_gen_dir}\device\bluetooth\public\mojom\adapter.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_ADAPTER_PAGE_JS"
+ file="adapter_page.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_CHARACTERISTIC_LIST_JS"
+ file="characteristic_list.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_CSS"
+ file="bluetooth_internals.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DESCRIPTOR_LIST_JS"
+ file="descriptor_list.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_BROKER_JS"
+ file="device_broker.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_COLLECTION_JS"
+ file="device_collection.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_DETAILS_PAGE_JS"
+ file="device_details_page.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_MOJO_JS"
+ file="${root_gen_dir}\device\bluetooth\public\mojom\device.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICE_TABLE_JS"
+ file="device_table.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEVICES_PAGE_JS"
+ file="devices_page.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_EXPANDABLE_LIST_JS"
+ file="expandable_list.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_HTML"
+ file="bluetooth_internals.html"
+ flattenhtml="true"
+ allowexternalscript="true"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_JS"
+ file="bluetooth_internals.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_MOJO_JS"
+ file="${root_gen_dir}\chrome\browser\ui\webui\bluetooth_internals\bluetooth_internals.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_OBJECT_FIELDSET_JS"
+ file="object_fieldset.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_SERVICE_LIST_JS"
+ file="service_list.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_SIDEBAR_JS"
+ file="sidebar.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_SNACKBAR_JS"
+ file="snackbar.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_UUID_MOJO_JS"
+ file="${root_gen_dir}\device\bluetooth\public\mojom\uuid.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_VALUE_CONTROL_JS"
+ file="value_control.js"
+ type="BINDATA"
+ compress="gzip" />
+ </includes>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/bookmarks/command_manager.js b/chromium/chrome/browser/resources/bookmarks/command_manager.js
index a1675b32d14..3d83ab732f6 100644
--- a/chromium/chrome/browser/resources/bookmarks/command_manager.js
+++ b/chromium/chrome/browser/resources/bookmarks/command_manager.js
@@ -214,7 +214,11 @@ cr.define('bookmarks', function() {
isCommandVisible_: function(command, itemIds) {
switch (command) {
case Command.EDIT:
+ case Command.PASTE:
return itemIds.size == 1 && this.globalCanEdit_;
+ case Command.CUT:
+ case Command.COPY:
+ return itemIds.size >= 1 && this.globalCanEdit_;
case Command.COPY_URL:
return this.isSingleBookmark_(itemIds);
case Command.DELETE:
@@ -269,6 +273,8 @@ cr.define('bookmarks', function() {
return this.canChangeList_();
case Command.IMPORT:
return this.globalCanEdit_;
+ case Command.PASTE:
+ return true; // TODO(hcarmona): Add check for CanPasteFromClipboard.
default:
return true;
}
@@ -613,9 +619,18 @@ cr.define('bookmarks', function() {
const itemUrl = this.getState().nodes[id].url;
label = itemUrl ? 'menuEdit' : 'menuRename';
break;
+ case Command.CUT:
+ label = 'menuCut';
+ break;
+ case Command.COPY:
+ label = 'menuCopy';
+ break;
case Command.COPY_URL:
label = 'menuCopyURL';
break;
+ case Command.PASTE:
+ label = 'menuPaste';
+ break;
case Command.DELETE:
label = 'menuDelete';
break;
@@ -681,10 +696,14 @@ cr.define('bookmarks', function() {
case MenuSource.TREE:
return [
Command.EDIT,
- Command.COPY_URL,
Command.SHOW_IN_FOLDER,
Command.DELETE,
// <hr>
+ Command.CUT,
+ Command.COPY,
+ Command.COPY_URL,
+ Command.PASTE,
+ // <hr>
Command.OPEN_NEW_TAB,
Command.OPEN_NEW_WINDOW,
Command.OPEN_INCOGNITO,
@@ -732,11 +751,17 @@ cr.define('bookmarks', function() {
* @private
*/
showDividerAfter_: function(command, itemIds) {
- return ((command == Command.SORT || command == Command.ADD_FOLDER ||
- command == Command.EXPORT) &&
- this.menuSource_ == MenuSource.TOOLBAR) ||
- (command == Command.DELETE &&
- (this.globalCanEdit_ || this.isSingleBookmark_(itemIds)));
+ switch (command) {
+ case Command.SORT:
+ case Command.ADD_FOLDER:
+ case Command.EXPORT:
+ return this.menuSource_ == MenuSource.TOOLBAR;
+ case Command.DELETE:
+ return this.globalCanEdit_;
+ case Command.PASTE:
+ return this.globalCanEdit_ || this.isSingleBookmark_(itemIds);
+ }
+ return false;
},
/**
diff --git a/chromium/chrome/browser/resources/bookmarks/folder_node.html b/chromium/chrome/browser/resources/bookmarks/folder_node.html
index bfb8b4da408..4c57f2ad54d 100644
--- a/chromium/chrome/browser/resources/bookmarks/folder_node.html
+++ b/chromium/chrome/browser/resources/bookmarks/folder_node.html
@@ -24,7 +24,7 @@
height: 40px;
min-width: fit-content;
overflow: hidden;
- padding-inline-start: calc(var(--node-depth, 0) * 10px);
+ padding-inline-start: calc(var(--node-depth, 0) * 15px);
}
#arrow {
diff --git a/chromium/chrome/browser/resources/bookmarks/folder_node.js b/chromium/chrome/browser/resources/bookmarks/folder_node.js
index dea00a6ebae..a540184a601 100644
--- a/chromium/chrome/browser/resources/bookmarks/folder_node.js
+++ b/chromium/chrome/browser/resources/bookmarks/folder_node.js
@@ -79,10 +79,7 @@ Polymer({
this.updateFromStore();
},
- /**
- * Overriden from bookmarks.MouseFocusBehavior.
- * @return {!HTMLElement}
- */
+ /** @return {!HTMLElement} */
getFocusTarget: function() {
return this.$.container;
},
diff --git a/chromium/chrome/browser/resources/bookmarks/item.html b/chromium/chrome/browser/resources/bookmarks/item.html
index c4fc5e0d617..9191430e622 100644
--- a/chromium/chrome/browser/resources/bookmarks/item.html
+++ b/chromium/chrome/browser/resources/bookmarks/item.html
@@ -107,7 +107,8 @@
id="menuButton"
tabindex="[[ironListTabIndex]]"
title="$i18n{moreActionsButtonTitle}"
- aria-label$="[[getButtonAriaLabel_(item_)]]"
+ aria-label$="[[getButtonAriaLabel_(item_, isSelectedItem_,
+ isMultiSelect_)]]"
on-click="onMenuButtonClick_"
aria-haspopup="menu"></cr-icon-button>
</template>
diff --git a/chromium/chrome/browser/resources/bookmarks/item.js b/chromium/chrome/browser/resources/bookmarks/item.js
index f013a78094c..e2f0aa78f08 100644
--- a/chromium/chrome/browser/resources/bookmarks/item.js
+++ b/chromium/chrome/browser/resources/bookmarks/item.js
@@ -36,6 +36,9 @@ Polymer({
},
/** @private */
+ isMultiSelect_: Boolean,
+
+ /** @private */
isFolder_: Boolean,
/** @private */
@@ -66,6 +69,7 @@ Polymer({
this.watch('item_', store => store.nodes[this.itemId]);
this.watch(
'isSelectedItem_', store => store.selection.items.has(this.itemId));
+ this.watch('isMultiSelect_', store => store.selection.items.size > 1);
this.updateFromStore();
},
@@ -113,7 +117,12 @@ Polymer({
onMenuButtonClick_: function(e) {
e.stopPropagation();
e.preventDefault();
- this.selectThisItem_();
+
+ // Skip selecting the item if this item is part of a multi-selected group.
+ if (!this.isMultiSelectMenu_()) {
+ this.selectThisItem_();
+ }
+
this.fire('open-command-menu', {
targetElement: e.target,
source: MenuSource.ITEM,
@@ -248,12 +257,32 @@ Polymer({
updateFavicon_: function(url) {
this.$.icon.className = url ? 'website-icon' : 'folder-icon';
this.$.icon.style.backgroundImage =
- url ? cr.icon.getFavicon(url, false) : null;
+ url ? cr.icon.getFaviconForPageURL(url, false) : null;
},
- /** @private */
+ /**
+ * @return {string}
+ * @private
+ */
getButtonAriaLabel_: function() {
+ if (!this.item_) {
+ return ''; // Item hasn't loaded, skip for now.
+ }
+
+ if (this.isMultiSelectMenu_()) {
+ return loadTimeData.getStringF('moreActionsMultiButtonAxLabel');
+ }
+
return loadTimeData.getStringF(
'moreActionsButtonAxLabel', this.item_.title);
- }
+ },
+
+ /**
+ * This item is part of a group selection.
+ * @return {boolean}
+ * @private
+ */
+ isMultiSelectMenu_: function() {
+ return this.isSelectedItem_ && this.isMultiSelect_;
+ },
});
diff --git a/chromium/chrome/browser/resources/bookmarks/shared_style.html b/chromium/chrome/browser/resources/bookmarks/shared_style.html
index 22bfc62568e..723f2db2e60 100644
--- a/chromium/chrome/browser/resources/bookmarks/shared_style.html
+++ b/chromium/chrome/browser/resources/bookmarks/shared_style.html
@@ -56,6 +56,9 @@
.folder-icon {
content: url(chrome://theme/IDR_FOLDER_CLOSED);
+ height: 20px;
+ min-width: 20px;
+ width: 20px;
}
<if expr="is_macosx or is_ios">
diff --git a/chromium/chrome/browser/resources/cast/OWNERS b/chromium/chrome/browser/resources/cast/OWNERS
deleted file mode 100644
index 5b34f4712ed..00000000000
--- a/chromium/chrome/browser/resources/cast/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-sheretov@chromium.org
diff --git a/chromium/chrome/browser/resources/cast/cast.css b/chromium/chrome/browser/resources/cast/cast.css
deleted file mode 100644
index 5193f40523b..00000000000
--- a/chromium/chrome/browser/resources/cast/cast.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2016 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. */
-
-body,
-extensionview,
-html {
- border: 0;
- height: 100%;
- margin: 0;
- padding: 0;
- width: 100%;
-}
-
-extensionview {
- overflow: hidden;
- position: absolute;
-}
diff --git a/chromium/chrome/browser/resources/cast/cast.html b/chromium/chrome/browser/resources/cast/cast.html
index 4510540eb9f..8247cee9ee7 100644
--- a/chromium/chrome/browser/resources/cast/cast.html
+++ b/chromium/chrome/browser/resources/cast/cast.html
@@ -3,13 +3,10 @@
<head>
<meta charset="utf-8">
<title>Google Cast</title>
- <link rel="stylesheet" href="cast.css">
- <link rel="shortcut icon" href="cast_favicon.ico">
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="strings.js"></script>
<script src="cast.js"></script>
</head>
<body>
- <extensionview></extensionview>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/cast/cast.js b/chromium/chrome/browser/resources/cast/cast.js
index 3cb9c1473de..75a7afbf4f6 100644
--- a/chromium/chrome/browser/resources/cast/cast.js
+++ b/chromium/chrome/browser/resources/cast/cast.js
@@ -2,37 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-window.addEventListener('load', function init() {
- const extensionView = document.querySelector('extensionview');
-
- /**
- * @param {string} str
- * @return {!Array<string>}
- */
- const splitUrlOnHash = function(str) {
- str = str || '';
- const pos = str.indexOf('#');
- return (pos !== -1) ? [str.substr(0, pos), str.substr(pos + 1)] : [str, ''];
- };
-
- new MutationObserver(function() {
- const newHash = splitUrlOnHash(extensionView.getAttribute('src'))[1];
- const oldHash = window.location.hash.substr(1);
- if (newHash !== oldHash) {
- window.location.hash = newHash;
- }
- }).observe(extensionView, {attributes: true});
-
- window.addEventListener('hashchange', function() {
- const newHash = window.location.hash.substr(1);
- const extensionViewSrcParts =
- splitUrlOnHash(extensionView.getAttribute('src'));
- if (newHash !== extensionViewSrcParts[1] && newHash.startsWith('offers')) {
- extensionView.load(extensionViewSrcParts[0] + '#' + newHash);
- }
- });
-
- extensionView.load(
- 'chrome-extension://' + loadTimeData.getString('extensionId') +
- '/cast_setup/index.html#offers');
-});
+window.location = 'chrome-extension://' +
+ loadTimeData.getString('extensionId') + '/cast_setup/index.html#offers';
diff --git a/chromium/chrome/browser/resources/cast/cast_favicon.ico b/chromium/chrome/browser/resources/cast/cast_favicon.ico
deleted file mode 100644
index 7f72553e0e8..00000000000
--- a/chromium/chrome/browser/resources/cast/cast_favicon.ico
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/chromeos/BUILD.gn b/chromium/chrome/browser/resources/chromeos/BUILD.gn
index 72b6c86c832..6d5a60739fa 100644
--- a/chromium/chrome/browser/resources/chromeos/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/BUILD.gn
@@ -47,7 +47,7 @@ grit("camera_resources") {
output_dir = "$root_gen_dir/chrome"
deps = [
- "//media/capture/video/chromeos/mojo:cros_camera_js",
+ "//media/capture/video/chromeos/mojom:cros_camera_js",
]
# The .grd contains references to generated files.
diff --git a/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
index 813d058f946..d41c627794d 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -158,6 +158,8 @@ copy("chrome_camera_app_js_models") {
"src/js/models/filenamer.js",
"src/js/models/filesystem.js",
"src/js/models/gallery.js",
+ "src/js/models/result_saver.js",
+ "src/js/models/video_saver.js",
]
outputs = [
@@ -167,7 +169,8 @@ copy("chrome_camera_app_js_models") {
copy("chrome_camera_app_js_mojo") {
sources = [
- "src/js/mojo/imagecapture.js",
+ "src/js/mojo/device_operator.js",
+ "src/js/mojo/image_capture.js",
]
outputs = [
@@ -232,17 +235,21 @@ copy("chrome_camera_app_views") {
copy("chrome_camera_app_mojo_generated") {
sources = [
"$root_gen_dir/media/capture/mojom/image_capture.mojom-lite.js",
- "$root_gen_dir/media/capture/video/chromeos/mojo/camera_common.mojom-lite.js",
- "$root_gen_dir/media/capture/video/chromeos/mojo/camera_metadata.mojom-lite.js",
- "$root_gen_dir/media/capture/video/chromeos/mojo/camera_metadata_tags.mojom-lite.js",
- "$root_gen_dir/media/capture/video/chromeos/mojo/cros_image_capture.mojom-lite.js",
+ "$root_gen_dir/media/capture/video/chromeos/mojom/camera_app.mojom-lite.js",
+ "$root_gen_dir/media/capture/video/chromeos/mojom/camera_common.mojom-lite.js",
+ "$root_gen_dir/media/capture/video/chromeos/mojom/camera_metadata.mojom-lite.js",
+ "$root_gen_dir/media/capture/video/chromeos/mojom/camera_metadata_tags.mojom-lite.js",
"$root_gen_dir/mojo/public/js/mojo_bindings_lite.js",
+ "$root_gen_dir/ui/gfx/geometry/mojom/geometry.mojom-lite.js",
+ "$root_gen_dir/ui/gfx/range/mojom/range.mojom-lite.js",
]
deps = [
"//media/capture/mojom:image_capture_js",
- "//media/capture/video/chromeos/mojo:cros_camera_js",
+ "//media/capture/video/chromeos/mojom:cros_camera_js",
"//mojo/public/js:bindings_lite",
+ "//ui/gfx/geometry/mojom:mojom_js",
+ "//ui/gfx/range/mojom:mojom_js",
]
outputs = [
diff --git a/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd b/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
index 0f24c24ff64..0a9ac124ab1 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
+++ b/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
@@ -18,6 +18,7 @@
<structure name="IDR_CAMERA_CAMERA3_DEVICE_INFO_JS" file="src/js/device/camera3_device_info.js" type="chrome_html" />
<structure name="IDR_CAMERA_CAMERA_JS" file="src/js/views/camera.js" type="chrome_html" />
<structure name="IDR_CAMERA_CONSTRAINTS_PREFERRER_JS" file="src/js/device/constraints_preferrer.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_DEVICE_OPERATOR_JS" file="src/js/mojo/device_operator.js" type="chrome_html" />
<structure name="IDR_CAMERA_DEVICE_INFO_UPDATER_JS" file="src/js/device/device_info_updater.js" type="chrome_html" />
<structure name="IDR_CAMERA_DIALOG_JS" file="src/js/views/dialog.js" type="chrome_html" />
<structure name="IDR_CAMERA_FILENAMER_JS" file="src/js/models/filenamer.js" type="chrome_html" />
@@ -25,7 +26,7 @@
<structure name="IDR_CAMERA_GALLERY_BASE_JS" file="src/js/views/gallery_base.js" type="chrome_html" />
<structure name="IDR_CAMERA_GALLERY_JS" file="src/js/models/gallery.js" type="chrome_html" />
<structure name="IDR_CAMERA_GALLERYBUTTON_JS" file="src/js/gallerybutton.js" type="chrome_html" />
- <structure name="IDR_CAMERA_IMAGECAPTURE_JS" file="src/js/mojo/imagecapture.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_IMAGECAPTURE_JS" file="src/js/mojo/image_capture.js" type="chrome_html" />
<structure name="IDR_CAMERA_LAYOUT_JS" file="src/js/views/camera/layout.js" type="chrome_html" />
<structure name="IDR_CAMERA_MAIN_CSS" file="src/css/main.css" type="chrome_html" />
<structure name="IDR_CAMERA_MAIN_HTML" file="src/views/main.html" type="chrome_html" />
@@ -38,6 +39,7 @@
<structure name="IDR_CAMERA_PREVIEW_JS" file="src/js/views/camera/preview.js" type="chrome_html" />
<structure name="IDR_CAMERA_RECORDTIME_JS" file="src/js/views/camera/recordtime.js" type="chrome_html" />
<structure name="IDR_CAMERA_RESOLUTION_EVENT_BROKER_JS" file="src/js/resolution_event_broker.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_RESULT_SAVER_JS" file="src/js/models/result_saver.js" type="chrome_html" />
<structure name="IDR_CAMERA_SCROLLBAR_JS" file="src/js/scrollbar.js" type="chrome_html" />
<structure name="IDR_CAMERA_SETTINGS_JS" file="src/js/views/settings.js" type="chrome_html" />
<structure name="IDR_CAMERA_SOUND_JS" file="src/js/sound.js" type="chrome_html" />
@@ -46,6 +48,7 @@
<structure name="IDR_CAMERA_TOAST_JS" file="src/js/toast.js" type="chrome_html" />
<structure name="IDR_CAMERA_TOOLTIP_JS" file="src/js/tooltip.js" type="chrome_html" />
<structure name="IDR_CAMERA_UTIL_JS" file="src/js/util.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_VIDEO_SAVER_JS" file="src/js/models/video_saver.js" type="chrome_html" />
<structure name="IDR_CAMERA_VIEW_JS" file="src/js/views/view.js" type="chrome_html" />
<structure name="IDR_CAMERA_WARNING_JS" file="src/js/views/warning.js" type="chrome_html" />
<structure name="IDR_CAMERA_WEBUI_BROWSER_PROXY" file="src/js/browser_proxy/webui_browser_proxy.js" type="chrome_html" />
@@ -57,19 +60,19 @@
use_base_dir="false"
type="BINDATA"/>
<include name="IDR_CAMERA_CAMERA_COMMON_MOJOM_LITE_JS"
- file="${root_gen_dir}/media/capture/video/chromeos/mojo/camera_common.mojom-lite.js"
+ file="${root_gen_dir}/media/capture/video/chromeos/mojom/camera_common.mojom-lite.js"
use_base_dir="false"
type="BINDATA"/>
<include name="IDR_CAMERA_CAMERA_METADATA_MOJOM_LITE_JS"
- file="${root_gen_dir}/media/capture/video/chromeos/mojo/camera_metadata.mojom-lite.js"
+ file="${root_gen_dir}/media/capture/video/chromeos/mojom/camera_metadata.mojom-lite.js"
use_base_dir="false"
type="BINDATA"/>
<include name="IDR_CAMERA_CAMERA_METADATA_TAGS_MOJOM_LITE_JS"
- file="${root_gen_dir}/media/capture/video/chromeos/mojo/camera_metadata_tags.mojom-lite.js"
+ file="${root_gen_dir}/media/capture/video/chromeos/mojom/camera_metadata_tags.mojom-lite.js"
use_base_dir="false"
type="BINDATA"/>
- <include name="IDR_CAMERA_CROS_IMAGE_CAPTURE_MOJOM_LITE_JS"
- file="${root_gen_dir}/media/capture/video/chromeos/mojo/cros_image_capture.mojom-lite.js"
+ <include name="IDR_CAMERA_APP_MOJOM_LITE_JS"
+ file="${root_gen_dir}/media/capture/video/chromeos/mojom/camera_app.mojom-lite.js"
use_base_dir="false"
type="BINDATA"/>
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json b/chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json
index 5a9f048411f..cf3600060c5 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json
@@ -45,6 +45,10 @@
"message": "Nothing recorded",
"description": "Error message shown when no data is recorded for a recording and it won't be added to the gallery."
},
+ "ERROR_MSG_EXPERT_MODE_NOT_SUPPORTED": {
+ "message": "Expert mode is not supported on this device",
+ "description": "Error message when the device does not support expert mode but tries to enable it."
+ },
"STATUS_MSG_RECORDING_STOPPED": {
"message": "Recording stopped",
"description": "Status message for spoken feedback when video recording has been stopped."
@@ -103,6 +107,18 @@
"message": "Camera resolution",
"description": "Label for the button of camera resolution options."
},
+ "EXPERT_MODE_BUTTON": {
+ "message": "Expert mode",
+ "description": "Label for the button of expert mode options."
+ },
+ "EXPERT_PREVIEW_METADATA": {
+ "message": "Preview metadata",
+ "description": "Label for expert mode option: preview metadata."
+ },
+ "EXPERT_SAVE_METADATA": {
+ "message": "Save metadata",
+ "description": "Label for expert mode option: save metadata."
+ },
"FEEDBACK_BUTTON": {
"message": "Send feedback",
"description": "Label for the feedback button."
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
index 7a0dd53b11e..059505eb02c 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
@@ -11,13 +11,16 @@ group("closure_compile") {
"device:closure_compile",
"models:closure_compile",
"mojo:closure_compile",
+ "views:closure_compile",
]
}
js_type_check("compile_resources") {
deps = [
+ ":nav",
":resolution_event_broker",
":state",
+ ":toast",
":tooltip",
":util",
]
@@ -26,9 +29,22 @@ js_type_check("compile_resources") {
js_library("resolution_event_broker") {
}
+js_library("nav") {
+ deps = [
+ "mojo:device_operator",
+ "views:view",
+ ]
+}
+
js_library("state") {
}
+js_library("toast") {
+ deps = [
+ ":util",
+ ]
+}
+
js_library("tooltip") {
}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn
index 013d454061a..cc01ba9b370 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn
@@ -14,22 +14,23 @@ js_type_check("closure_compile") {
js_library("camera3_device_info") {
deps = [
- "../mojo:imagecapture",
+ "../mojo:image_capture",
]
}
js_library("constraints_preferrer") {
deps = [
+ ":camera3_device_info",
"..:resolution_event_broker",
+ "..:state",
"../browser_proxy:browser_proxy",
]
}
js_library("device_info_updater") {
deps = [
- "..:state",
- "../mojo:imagecapture",
":camera3_device_info",
":constraints_preferrer",
+ "..:state",
]
}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/js/models/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/models/BUILD.gn
index 89ebf568fe6..db0f77e3e3f 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/models/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/models/BUILD.gn
@@ -9,6 +9,8 @@ js_type_check("closure_compile") {
":filenamer",
":filesystem",
":gallery",
+ ":result_saver",
+ ":video_saver",
]
}
@@ -26,3 +28,9 @@ js_library("gallery") {
":filesystem",
]
}
+
+js_library("result_saver") {
+}
+
+js_library("video_saver") {
+}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn
index 9d131abf33c..3be85b7f5c2 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn
@@ -6,14 +6,23 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
- ":imagecapture",
+ ":device_operator",
+ ":image_capture",
]
}
-js_library("imagecapture") {
+js_library("device_operator") {
deps = [
+ "//media/capture/video/chromeos/mojom:cros_camera_js_library_for_compile",
+ ]
+ externs_list = [ "$externs_path/pending.js" ]
+}
+
+js_library("image_capture") {
+ deps = [
+ ":device_operator",
+ "..:util",
"//media/capture/mojom:image_capture_js_library_for_compile",
- "//media/capture/video/chromeos/mojo:cros_camera_js_library_for_compile",
]
externs_list = [ "$externs_path/pending.js" ]
}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn
new file mode 100644
index 00000000000..84560373b2c
--- /dev/null
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn
@@ -0,0 +1,23 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+group("closure_compile") {
+ deps = [
+ ":compile_resources",
+ ]
+}
+
+js_type_check("compile_resources") {
+ deps = [
+ ":view",
+ ]
+}
+
+js_library("view") {
+ deps = [
+ "..:toast",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd b/chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd
index 834cc2109d1..299d99fff8c 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd
@@ -222,6 +222,18 @@
<message desc="Label for the checkbox to toggle the microphone for recording video." name="IDS_TOGGLE_MIC_BUTTON">
Microphone
</message>
+ <message desc="Label for the button of expert mode options." name="IDS_EXPERT_MODE_BUTTON">
+ Expert mode
+ </message>
+ <message desc="Label for expert mode option: preview metadata." name="IDS_EXPERT_PREVIEW_METADATA">
+ Preview metadata
+ </message>
+ <message desc="Label for expert mode option: save metadata." name="IDS_EXPERT_SAVE_METADATA">
+ Save metadata
+ </message>
+ <message desc="Error message when the device does not support expert mode but tries to enable it." name="IDS_ERROR_MSG_EXPERT_MODE_NOT_SUPPORTED">
+ Expert mode is not supported on this device
+ </message>
<message desc="Label for the feedback button." name="IDS_FEEDBACK_BUTTON">
Send feedback
</message>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
index 32d9da3e2e8..39bba1fa5d9 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -146,6 +146,7 @@ chromevox_modules = [
"cvox2/background/live_regions.js",
"cvox2/background/log.js",
"cvox2/background/log_store.js",
+ "cvox2/background/log_types.js",
"cvox2/background/math_handler.js",
"cvox2/background/media_automation_handler.js",
"cvox2/background/mouse_handler.js",
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
index 83d4ec0c1ad..2028ad38ee8 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -2971,25 +2971,18 @@ If you're done with the tutorial, use ChromeVox to navigate to the Close button
<message desc="Description of a command that toggles between 6 and 8 dot braille." name="IDS_CHROMEVOX_TOGGLE_BRAILLE_TABLE">
Toggle between 6 and 8 dot braille
</message>
- <message desc="Spoken when a user navigates to the beginning of a misspelled word." name="IDS_CHROMEVOX_MISSPELLING_START">
- Misspelling start
+ <message desc="Spoken when a user navigates into a misspelled word." name="IDS_CHROMEVOX_MISSPELLING_START">
+ Misspelled
</message>
- <message desc="Spoken when a user navigates to the end of a misspelled word." name="IDS_CHROMEVOX_MISSPELLING_END">
- Misspelling end
+ <message desc="Spoken when a user navigates out of a misspelled word." name="IDS_CHROMEVOX_MISSPELLING_END">
+ Leaving misspelled
</message>
- <message desc="Spoken when a user navigates to the beginning of a grammar error." name="IDS_CHROMEVOX_GRAMMAR_START">
- Grammar error start
+ <message desc="Spoken when a user navigates into a grammar error." name="IDS_CHROMEVOX_GRAMMAR_START">
+ Grammar error
</message>
- <message desc="Spoken when a user navigates to the end of a grammar error." name="IDS_CHROMEVOX_GRAMMAR_END">
- Grammar error end
+ <message desc="Spoken when a user navigates out of a grammar error." name="IDS_CHROMEVOX_GRAMMAR_END">
+ Leaving grammar error
</message>
- <message desc="Spoken when a user navigates to the beginning of a text match from a find in page." name="IDS_CHROMEVOX_TEXT_MATCH_START">
- Text match start
- </message>
- <message desc="Spoken when a user navigates to the end of a text match from a find in page." name="IDS_CHROMEVOX_TEXT_MATCH_END">
- Text match end
- </message>
-
<message desc="Spoken to describe text that is superscript." name="IDS_CHROMEVOX_SUPERSCRIPT">
Superscript
</message>
@@ -3221,7 +3214,7 @@ If you're done with the tutorial, use ChromeVox to navigate to the Close button
</message>
<message desc="The text label for ChromeVox language switching checkbox."
name="IDS_CHROMEVOX_OPTIONS_LANG_SWITCHING_CHECKBOX_LABEL">
- Automatically detect and switch ChromeVox language.
+ Automatically switch ChromeVox voice based on language
</message>
<message desc="Spoken to describe all rich text attributes of a node." name="IDS_CHROMEVOX_RICH_TEXT_ATTRIBUTES">
Text formatting.
@@ -3656,10 +3649,10 @@ If you're done with the tutorial, use ChromeVox to navigate to the Close button
Dodger Blue
</message>
<message desc="An options page section header for options about ChromeVox rich text behavior. This section lets users set preferences on how rich text attributes should be indicated." name="IDS_CHROMEVOX_OPTIONS_RICH_TEXT_HEADER">
- Rich Text Attributes
+ Formatting
</message>
<message desc="The text label for ChromeVox automatic rich text indication checkbox." name="IDS_CHROMEVOX_OPTIONS_RICH_TEXT_CHECKBOX_LABEL">
- Announce rich text attributes
+ Announce text styling
</message>
<message desc="Labels the misspell list box." name="IDS_CHROMEVOX_OPTIONS_MISSPELL_DESCRIPTION">
Indicate misspell:
diff --git a/chromium/chrome/browser/resources/chromeos/genius_app/manifest.json b/chromium/chrome/browser/resources/chromeos/genius_app/manifest.json
index e0f1b720490..c79cf9eda03 100644
--- a/chromium/chrome/browser/resources/chromeos/genius_app/manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/genius_app/manifest.json
@@ -3,7 +3,7 @@
"manifest_version": 2,
"name": "__MSG_app_name__",
"description": "__MSG_app_description__",
- "version": "0.3",
+ "version": "0.4",
"minimum_chrome_version": "28",
"default_locale": "en",
"incognito" : "split",
@@ -36,6 +36,7 @@
"https://*.ytimg.com/*",
"https://www.google.com/*",
"https://support.google.com/*",
+ "https://scone-pa.clients6.google.com/*",
"https://commondatastorage.googleapis.com/*",
"https://storage.googleapis.com/*",
"https://www.google-analytics.com/"
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 13434201e78..7f45f293dd0 100644
--- a/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
@@ -26,7 +26,7 @@ js_library("internet_detail_dialog") {
deps = [
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+ "//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/chromeos:onc_mojo",
diff --git a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
index 16625518952..77459dd1bf6 100644
--- a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -192,7 +192,8 @@ js_library("enrollment_license_card") {
js_library("fingerprint_setup") {
deps = [
":oobe_dialog_host_behavior",
- "//ui/webui/resources/cr_elements/chromeos/fingerprint:cr_fingerprint_progress_arc",
+ "//ui/webui/resources/cr_elements/chromeos/cr_lottie:cr_lottie",
+ "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc",
"//ui/webui/resources/js:i18n_behavior",
]
}
diff --git a/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn b/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
index 33cef10b2fc..a38c408d0f3 100644
--- a/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
@@ -36,7 +36,10 @@ run_jsbundler("switch_access_copied_files") {
"back_button_manager.js",
"background.js",
"commands.js",
+ "focus_ring_manager.js",
"icons/back.svg",
+ "icons/copy.svg",
+ "icons/cut.svg",
"icons/decrement.svg",
"icons/dictation.svg",
"icons/increment.svg",
@@ -45,29 +48,27 @@ run_jsbundler("switch_access_copied_files") {
"icons/keyboard.svg",
"icons/moveBackwardOneCharOfText.svg",
"icons/moveBackwardOneWordOfText.svg",
+ "icons/moveCursor.svg",
"icons/moveDownOneLineOfText.svg",
"icons/moveForwardOneCharOfText.svg",
"icons/moveForwardOneWordOfText.svg",
"icons/moveUpOneLineOfText.svg",
- "icons/options.svg",
+ "icons/paste.svg",
"icons/scrollDownOrForward.svg",
"icons/scrollLeft.svg",
"icons/scrollRight.svg",
"icons/scrollUpOrBackward.svg",
"icons/select.svg",
+ "icons/settings.svg",
"icons/showContextMenu.svg",
"icons/textSelectionEnd.svg",
"icons/textSelectionStart.svg",
- "key_event_handler.js",
"menu_manager.js",
"menu_panel.css",
"menu_panel.html",
"menu_panel.js",
"menu_panel_interface.js",
"navigation_manager.js",
- "options.css",
- "options.html",
- "options.js",
"preferences.js",
"rect_helper.js",
"switch_access.js",
@@ -174,12 +175,11 @@ js_type_check("closure_compile") {
":back_button_manager",
":background",
":commands",
- ":key_event_handler",
+ ":focus_ring_manager",
":menu_manager",
":menu_panel",
":menu_panel_interface",
":navigation_manager",
- ":options",
":preferences",
":rect_helper",
":switch_access",
@@ -203,10 +203,12 @@ js_library("auto_scan_manager") {
js_library("navigation_manager") {
deps = [
":back_button_manager",
+ ":focus_ring_manager",
":menu_manager",
":menu_panel_interface",
":rect_helper",
":switch_access_constants",
+ ":switch_access_interface",
":switch_access_predicate",
":text_input_manager",
":text_navigation_manager",
@@ -242,9 +244,9 @@ js_library("commands") {
]
}
-js_library("key_event_handler") {
+js_library("focus_ring_manager") {
deps = [
- ":switch_access_interface",
+ ":back_button_manager",
]
externs_list = [ "$externs_path/accessibility_private.js" ]
}
@@ -254,6 +256,7 @@ js_library("menu_manager") {
":menu_panel_interface",
":switch_access_interface",
]
+ externs_list = [ "$externs_path/accessibility_private.js" ]
}
js_library("menu_panel") {
@@ -265,19 +268,11 @@ js_library("menu_panel") {
js_library("menu_panel_interface") {
}
-js_library("options") {
- deps = [
- ":background",
- ":switch_access",
- ]
- externs_list = [ "$externs_path/chrome_extensions.js" ]
-}
-
js_library("preferences") {
deps = [
":switch_access_interface",
]
- externs_list = [ "$externs_path/chrome_extensions.js" ]
+ externs_list = [ "$externs_path/settings_private.js" ]
}
js_library("rect_helper") {
@@ -288,7 +283,6 @@ js_library("switch_access") {
deps = [
":auto_scan_manager",
":commands",
- ":key_event_handler",
":menu_panel_interface",
":navigation_manager",
":preferences",
@@ -296,6 +290,7 @@ js_library("switch_access") {
externs_list = [
"$externs_path/automation.js",
"$externs_path/chrome_extensions.js",
+ "$externs_path/clipboard.js",
"$externs_path/command_line_private.js",
]
}
diff --git a/chromium/chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd b/chromium/chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd
index 637e823fe73..6795d3cbda3 100644
--- a/chromium/chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd
+++ b/chromium/chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd
@@ -162,6 +162,9 @@
<message desc="The Switch Access action to open the Switch Access settings page. Should be short." name="IDS_SWITCH_ACCESS_SETTINGS_ACTION">
Settings
</message>
+ <message desc="The Switch Access action to show the text navigation menu for moving the text caret within a text element." name="IDS_SWITCH_ACCESS_MOVE_CURSOR">
+ Move cursor
+ </message>
<message desc="The Switch Access action for moving the text caret to the beginning of the text element." name="IDS_SWITCH_ACCESS_JUMP_TO_BEGINNING_OF_TEXT">
Jump to beginning
</message>
@@ -192,6 +195,15 @@
<message desc="The Switch Access action to set the end of a text selection area." name="IDS_SWITCH_ACCESS_SELECTION_END">
Selection end
</message>
+ <message desc="The Switch Access action to cut text." name="IDS_SWITCH_ACCESS_CUT">
+ Cut
+ </message>
+ <message desc="The Switch Access action to copy text." name="IDS_SWITCH_ACCESS_COPY">
+ Copy
+ </message>
+ <message desc="The Switch Access action to paste text." name="IDS_SWITCH_ACCESS_PASTE">
+ Paste
+ </message>
</messages>
</release>
</grit>
diff --git a/chromium/chrome/browser/resources/component_extension_resources.grd b/chromium/chrome/browser/resources/component_extension_resources.grd
index 21fb200503d..f159f9a242b 100644
--- a/chromium/chrome/browser/resources/component_extension_resources.grd
+++ b/chromium/chrome/browser/resources/component_extension_resources.grd
@@ -103,7 +103,6 @@
<include name="IDR_PDF_TOOLBAR_MANAGER_JS" file="pdf/toolbar_manager.js" type="BINDATA" />
<include name="IDR_PDF_PDF_FITTING_TYPE_JS" file="pdf/pdf_fitting_type.js" type="BINDATA" />
<include name="IDR_PDF_VIEWPORT_JS" file="pdf/viewport.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWPORT_INTERFACE_JS" file="pdf/viewport_interface.js" type="BINDATA" />
<include name="IDR_PDF_OPEN_PDF_PARAMS_PARSER_JS" file="pdf/open_pdf_params_parser.js" type="BINDATA" />
<include name="IDR_PDF_NAVIGATOR_JS" file="pdf/navigator.js" type="BINDATA" />
<include name="IDR_PDF_VIEWPORT_SCROLLER_JS" file="pdf/viewport_scroller.js" type="BINDATA" />
@@ -117,8 +116,6 @@
<include name="IDR_PDF_ICONS_HTML" file="pdf/elements/icons.html" type="BINDATA" />
<include name="IDR_PDF_VIEWER_BOOKMARK_HTML" file="pdf/elements/viewer-bookmark/viewer-bookmark.html" type="BINDATA" />
<include name="IDR_PDF_VIEWER_BOOKMARK_JS" file="pdf/elements/viewer-bookmark/viewer-bookmark.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_BOOKMARKS_CONTENT_HTML" file="pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_BOOKMARKS_CONTENT_JS" file="pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js" type="BINDATA" />
<include name="IDR_PDF_VIEWER_ERROR_SCREEN_HTML" file="pdf/elements/viewer-error-screen/viewer-error-screen.html" type="BINDATA" />
<include name="IDR_PDF_VIEWER_ERROR_SCREEN_JS" file="pdf/elements/viewer-error-screen/viewer-error-screen.js" type="BINDATA" />
<if expr="chromeos">
diff --git a/chromium/chrome/browser/resources/cryptotoken/cryptotokenbackground.js b/chromium/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
index 13c0e886205..977b3804a0d 100644
--- a/chromium/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
+++ b/chromium/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
@@ -9,9 +9,6 @@
'use strict';
/** @const */
-var BROWSER_SUPPORTS_TLS_CHANNEL_ID = true;
-
-/** @const */
var HTTP_ORIGINS_ALLOWED = false;
/** @const */
diff --git a/chromium/chrome/browser/resources/cryptotoken/enroller.js b/chromium/chrome/browser/resources/cryptotoken/enroller.js
index 4fb1bef7c44..7bde035b0a1 100644
--- a/chromium/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chromium/chrome/browser/resources/cryptotoken/enroller.js
@@ -1119,8 +1119,8 @@ Enroller.prototype.encodeEnrollChallenges_ = function(
// which we're constructing here. The browser data object contains, among
// other things, the server challenge.
var serverChallenge = enrollChallenge['challenge'];
- var browserData = makeEnrollBrowserData(
- serverChallenge, this.sender_.origin, this.sender_.tlsChannelId);
+ var browserData =
+ makeEnrollBrowserData(serverChallenge, this.sender_.origin);
// Replace the challenge with the hash of the browser data.
modifiedChallenge['challenge'] =
B64_encode(sha256HashOfString(browserData));
diff --git a/chromium/chrome/browser/resources/cryptotoken/manifest.json b/chromium/chrome/browser/resources/cryptotoken/manifest.json
index dec5bb9e130..d6a8329a3e0 100644
--- a/chromium/chrome/browser/resources/cryptotoken/manifest.json
+++ b/chromium/chrome/browser/resources/cryptotoken/manifest.json
@@ -17,8 +17,7 @@
],
"ids": [
"fjajfjhkeibgmiggdfehjplbhmfkialk"
- ],
- "accepts_tls_channel_id": true
+ ]
},
"background": {
"persistent": false,
diff --git a/chromium/chrome/browser/resources/cryptotoken/signer.js b/chromium/chrome/browser/resources/cryptotoken/signer.js
index 5dae63eedf8..30cd3ca9097 100644
--- a/chromium/chrome/browser/resources/cryptotoken/signer.js
+++ b/chromium/chrome/browser/resources/cryptotoken/signer.js
@@ -445,8 +445,7 @@ Signer.prototype.doSign_ = async function() {
}
var keyHandle = challenge['keyHandle'];
- var browserData = makeSignBrowserData(
- serverChallenge, this.sender_.origin, this.sender_.tlsChannelId);
+ var browserData = makeSignBrowserData(serverChallenge, this.sender_.origin);
this.browserData_[keyHandle] = browserData;
this.serverChallenges_[keyHandle] = challenge;
}
diff --git a/chromium/chrome/browser/resources/cryptotoken/webrequest.js b/chromium/chrome/browser/resources/cryptotoken/webrequest.js
index d9c9b4fc9d0..1bd2c3d0e8b 100644
--- a/chromium/chrome/browser/resources/cryptotoken/webrequest.js
+++ b/chromium/chrome/browser/resources/cryptotoken/webrequest.js
@@ -258,58 +258,20 @@ function sha256HashOfString(string) {
var UNUSED_CID_PUBKEY_VALUE = 'unused';
/**
- * Normalizes the TLS channel ID value:
- * 1. Converts semantically empty values (undefined, null, 0) to the empty
- * string.
- * 2. Converts valid JSON strings to a JS object.
- * 3. Otherwise, returns the input value unmodified.
- * @param {Object|string|undefined} opt_tlsChannelId TLS Channel id
- * @return {Object|string} The normalized TLS channel ID value.
- */
-function tlsChannelIdValue(opt_tlsChannelId) {
- if (!opt_tlsChannelId) {
- // Case 1: Always set some value for TLS channel ID, even if it's the empty
- // string: this browser definitely supports them.
- return UNUSED_CID_PUBKEY_VALUE;
- }
- if (typeof opt_tlsChannelId === 'string') {
- try {
- var obj = JSON.parse(opt_tlsChannelId);
- if (!obj) {
- // Case 1: The string value 'null' parses as the Javascript object null,
- // so return an empty string: the browser definitely supports TLS
- // channel id.
- return UNUSED_CID_PUBKEY_VALUE;
- }
- // Case 2: return the value as a JS object.
- return /** @type {Object} */ (obj);
- } catch (e) {
- console.warn('Unparseable TLS channel ID value ' + opt_tlsChannelId);
- // Case 3: return the value unmodified.
- }
- }
- return opt_tlsChannelId;
-}
-
-/**
* Creates a browser data object with the given values.
* @param {!string} type A string representing the "type" of this browser data
* object.
* @param {!string} serverChallenge The server's challenge, as a base64-
* encoded string.
* @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
* @return {string} A string representation of the browser data object.
*/
-function makeBrowserData(type, serverChallenge, origin, opt_tlsChannelId) {
+function makeBrowserData(type, serverChallenge, origin) {
var browserData = {
'typ': type,
'challenge': serverChallenge,
'origin': origin
};
- if (BROWSER_SUPPORTS_TLS_CHANNEL_ID) {
- browserData['cid_pubkey'] = tlsChannelIdValue(opt_tlsChannelId);
- }
return JSON.stringify(browserData);
}
@@ -318,13 +280,11 @@ function makeBrowserData(type, serverChallenge, origin, opt_tlsChannelId) {
* @param {!string} serverChallenge The server's challenge, as a base64-
* encoded string.
* @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
* @return {string} A string representation of the browser data object.
*/
-function makeEnrollBrowserData(serverChallenge, origin, opt_tlsChannelId) {
+function makeEnrollBrowserData(serverChallenge, origin) {
return makeBrowserData(
- 'navigator.id.finishEnrollment', serverChallenge, origin,
- opt_tlsChannelId);
+ 'navigator.id.finishEnrollment', serverChallenge, origin);
}
/**
@@ -332,12 +292,10 @@ function makeEnrollBrowserData(serverChallenge, origin, opt_tlsChannelId) {
* @param {!string} serverChallenge The server's challenge, as a base64-
* encoded string.
* @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
* @return {string} A string representation of the browser data object.
*/
-function makeSignBrowserData(serverChallenge, origin, opt_tlsChannelId) {
- return makeBrowserData(
- 'navigator.id.getAssertion', serverChallenge, origin, opt_tlsChannelId);
+function makeSignBrowserData(serverChallenge, origin) {
+ return makeBrowserData('navigator.id.getAssertion', serverChallenge, origin);
}
/**
diff --git a/chromium/chrome/browser/resources/cryptotoken/webrequestsender.js b/chromium/chrome/browser/resources/cryptotoken/webrequestsender.js
index 4b54896c085..9630de47e9d 100644
--- a/chromium/chrome/browser/resources/cryptotoken/webrequestsender.js
+++ b/chromium/chrome/browser/resources/cryptotoken/webrequestsender.js
@@ -11,7 +11,6 @@
/**
* @typedef {{
* origin: string,
- * tlsChannelId: (string|undefined),
* tabId: (number|undefined)
* }}
*/
@@ -30,9 +29,6 @@ function createSenderFromMessageSender(messageSender) {
return null;
}
var sender = {origin: origin};
- if (messageSender.tlsChannelId) {
- sender.tlsChannelId = messageSender.tlsChannelId;
- }
if (messageSender.tab) {
sender.tabId = messageSender.tab.id;
}
diff --git a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css
new file mode 100644
index 00000000000..aa35e0acfab
--- /dev/null
+++ b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css
@@ -0,0 +1,45 @@
+/* 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. */
+
+body {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ font-family: sans, Arial, sans-serif;
+ font-size: 93.75%;
+ justify-content: flex-start;
+}
+
+/* This is needed to hide elements that have "display" set. */
+[hidden] {
+ display: none !important;
+}
+
+#failure-message {
+ display: inline-block;
+ padding-top: 100px;
+}
+
+h1.heading {
+ color: rgb(32, 33, 36);
+ font-size: 1.6em;
+ font-weight: normal;
+ line-height: 1.25em;
+ margin: 0 0 15px 0;
+}
+
+.list-header {
+ color: #2B2B2B;
+ line-height: 1.61em;
+ margin: 0 8px 0 0;
+}
+
+ul.suggestions-list {
+ margin-top: 0;
+}
+
+ul.suggestions-list li {
+ color: #2B2B2B;
+ line-height: 1.55;
+}
diff --git a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.grdp b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.grdp
new file mode 100644
index 00000000000..547e30b812d
--- /dev/null
+++ b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.grdp
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_DEV_UI_LOADER_HTML" file="resources/dev_ui_loader/dev_ui_loader.html" compress="gzip" type="BINDATA" />
+ <include name="IDR_DEV_UI_LOADER_CSS" file="resources/dev_ui_loader/dev_ui_loader.css" compress="gzip" type="BINDATA" />
+ <include name="IDR_DEV_UI_LOADER_JS" file="resources/dev_ui_loader/dev_ui_loader.js" compress="gzip" type="BINDATA" />
+</grit-part>
diff --git a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.html b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.html
new file mode 100644
index 00000000000..fc95229fb39
--- /dev/null
+++ b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>DevUI DFM Loader</title>
+ <link rel="stylesheet" href="dev_ui_loader.css">
+ <script src="chrome://resources/js/cr.js"></script>
+ <script src="chrome://resources/js/promise_resolver.js"></script>
+ <script src="dev_ui_loader.js"></script>
+</head>
+<body>
+<div id="failure-message" hidden>
+ <h1 class="heading">Something went wrong</h1>
+ <p class="list-header">Try:</p>
+ <ul class="suggestions-list">
+ <li>Reloading this page</li>
+ <li>Checking your internet connection</li>
+ </ul>
+</div>
+</body>
+</html>
diff --git a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.js b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.js
new file mode 100644
index 00000000000..61bc4c25be8
--- /dev/null
+++ b/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.js
@@ -0,0 +1,51 @@
+// 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.
+
+(function() {
+'use strict';
+
+/** @return {!URL} */
+function getRedirectUrl() {
+ try { // For potential TypeError from new URL().
+ const urlString = new URL(location).searchParams.get('url');
+ if (urlString) {
+ const url = new URL(decodeURIComponent(urlString));
+ // Perform basic filtering. Also skip 'dev-ui-loader' to avoid redirect
+ // cycle (benign but bizarre). Note that |url.host| is always lowercase.
+ if (url.protocol === 'chrome:' && url.host.match(/[a-z0-9_\-]+/) &&
+ url.host !== 'dev-ui-loader') {
+ return url;
+ }
+ }
+ } catch (e) {
+ }
+ return new URL('chrome://chrome-urls');
+}
+
+function redirectToChromePage() {
+ // Use replace() so the current page disappears from history.
+ location.replace(getRedirectUrl());
+}
+
+function doInstall() {
+ cr.sendWithPromise('installAndLoadDevUiDfm').then((response) => {
+ const status = response[0];
+ if (status === 'success' || status === 'noop') {
+ redirectToChromePage();
+ } else if (status === 'failure') {
+ document.querySelector('#failure-message').hidden = false;
+ }
+ });
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ cr.sendWithPromise('getDevUiDfmState').then((state) => {
+ if (state === 'ready') {
+ redirectToChromePage();
+ } else if (state === 'not-installed' || 'not-loaded') {
+ doInstall();
+ }
+ });
+});
+})();
diff --git a/chromium/chrome/browser/resources/device_log_ui/device_log_ui.js b/chromium/chrome/browser/resources/device_log_ui/device_log_ui.js
index 11103072caa..2e4181171db 100644
--- a/chromium/chrome/browser/resources/device_log_ui/device_log_ui.js
+++ b/chromium/chrome/browser/resources/device_log_ui/device_log_ui.js
@@ -124,9 +124,9 @@ const DeviceLogUI = (function() {
* Sets refresh rate if the interval is found in the url.
*/
const setRefresh = function() {
- const interval = parseQueryParams(window.location)['refresh'];
- if (interval && interval != '') {
- setInterval(requestLog, parseInt(interval) * 1000);
+ const interval = new URL(window.location).searchParams.get('refresh');
+ if (interval) {
+ setInterval(requestLog, parseInt(interval, 10) * 1000);
}
};
diff --git a/chromium/chrome/browser/resources/discards/discards_tab.js b/chromium/chrome/browser/resources/discards/discards_tab.js
index fd729e3119a..b7a64869944 100644
--- a/chromium/chrome/browser/resources/discards/discards_tab.js
+++ b/chromium/chrome/browser/resources/discards/discards_tab.js
@@ -295,7 +295,8 @@ Polymer({
* @private
*/
getFavIconStyle_: function(item) {
- return 'background-image:' + cr.icon.getFavicon(item.tabUrl, false);
+ return 'background-image:' +
+ cr.icon.getFaviconForPageURL(item.tabUrl, false);
},
/**
diff --git a/chromium/chrome/browser/resources/downloads/item.js b/chromium/chrome/browser/resources/downloads/item.js
index 5eb28c74d35..dff416ea746 100644
--- a/chromium/chrome/browser/resources/downloads/item.js
+++ b/chromium/chrome/browser/resources/downloads/item.js
@@ -474,7 +474,13 @@ cr.define('downloads', function() {
// Make the file name collapsible.
p.collapsible = !!p.arg;
});
- cr.toastManager.getInstance().showForStringPieces(pieces, true);
+ cr.toastManager.getInstance().showForStringPieces(
+ /**
+ * @type {!Array<{collapsible: boolean,
+ * value: string,
+ * arg: (string|null)}>}
+ */
+ (pieces), true);
this.mojoHandler_.remove(this.data.id);
},
diff --git a/chromium/chrome/browser/resources/extensions/BUILD.gn b/chromium/chrome/browser/resources/extensions/BUILD.gn
index 7a60d45137f..1798f6238a7 100644
--- a/chromium/chrome/browser/resources/extensions/BUILD.gn
+++ b/chromium/chrome/browser/resources/extensions/BUILD.gn
@@ -165,6 +165,7 @@ js_library("item") {
":item_behavior",
":item_util",
":navigation_helper",
+ "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:i18n_behavior",
@@ -370,7 +371,7 @@ js_library("sidebar") {
js_library("toolbar") {
deps = [
"//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
- "//ui/webui/resources/cr_elements/cr_toast:cr_toast",
+ "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:util",
diff --git a/chromium/chrome/browser/resources/extensions/item.html b/chromium/chrome/browser/resources/extensions/item.html
index 4dd4b1c830c..a69c6b4c656 100644
--- a/chromium/chrome/browser/resources/extensions/item.html
+++ b/chromium/chrome/browser/resources/extensions/item.html
@@ -3,6 +3,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast_manager.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
diff --git a/chromium/chrome/browser/resources/extensions/item.js b/chromium/chrome/browser/resources/extensions/item.js
index 008beca6c32..d1fc8e973ab 100644
--- a/chromium/chrome/browser/resources/extensions/item.js
+++ b/chromium/chrome/browser/resources/extensions/item.js
@@ -117,6 +117,9 @@ cr.define('extensions', function() {
},
},
+ /** Prevents reloading the same item while it's already being reloaded. */
+ isReloading_: false,
+
observers: [
'observeIdVisibility_(inDevMode, showingDetails_, data.id)',
],
@@ -213,9 +216,30 @@ cr.define('extensions', function() {
/** @private */
onReloadTap_: function() {
- this.delegate.reloadItem(this.data.id).catch(loadError => {
- this.fire('load-error', loadError);
- });
+ // Don't reload if in the middle of an update.
+ if (this.isReloading_) {
+ return;
+ }
+
+ this.isReloading_ = true;
+
+ const toastManager = cr.toastManager.getInstance();
+ // Keep the toast open indefinitely.
+ toastManager.duration = 0;
+ toastManager.show(this.i18n('itemReloading'), false);
+ this.delegate.reloadItem(this.data.id)
+ .then(
+ () => {
+ toastManager.hide();
+ toastManager.duration = 3000;
+ toastManager.show(this.i18n('itemReloaded'), false);
+ this.isReloading_ = false;
+ },
+ loadError => {
+ this.fire('load-error', loadError);
+ toastManager.hide();
+ this.isReloading_ = false;
+ });
},
/** @private */
diff --git a/chromium/chrome/browser/resources/extensions/manager.html b/chromium/chrome/browser/resources/extensions/manager.html
index 0acd9673c75..1c35c285068 100644
--- a/chromium/chrome/browser/resources/extensions/manager.html
+++ b/chromium/chrome/browser/resources/extensions/manager.html
@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_drawer/cr_drawer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast_manager.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
<link rel="import" href="chrome://resources/cr_elements/cr_view_manager/cr_view_manager.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
@@ -138,6 +139,7 @@
install-warnings="[[installWarnings_]]">
</extensions-install-warnings-dialog>
</template>
+ <cr-toast-manager></cr-toast-manager>
</template>
<script src="manager.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/extensions/toolbar.html b/chromium/chrome/browser/resources/extensions/toolbar.html
index 7e08974284a..9b8706bd762 100644
--- a/chromium/chrome/browser/resources/extensions/toolbar.html
+++ b/chromium/chrome/browser/resources/extensions/toolbar.html
@@ -1,7 +1,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast_manager.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
@@ -91,14 +91,6 @@
.more-actions span {
margin-inline-end: 16px;
}
-
- cr-toast > div {
- display: flex;
- flex: 1;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
</style>
<cr-toolbar page-name="$i18n{toolbarTitle}" search-prompt="$i18n{search}"
clear-label="$i18n{clearSearch}" menu-label="$i18n{mainMenu}" show-menu
@@ -143,9 +135,6 @@
</if>
</div>
</div>
- <cr-toast>
- <div>[[toastLabel_]]</div>
- </cr-toast>
</template>
<script src="toolbar.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/extensions/toolbar.js b/chromium/chrome/browser/resources/extensions/toolbar.js
index 7792f175221..bd3590edcba 100644
--- a/chromium/chrome/browser/resources/extensions/toolbar.js
+++ b/chromium/chrome/browser/resources/extensions/toolbar.js
@@ -55,12 +55,6 @@ cr.define('extensions', function() {
showPackDialog_: Boolean,
/**
- * Text to display in update toast
- * @private
- */
- toastLabel_: String,
-
- /**
* Prevents initiating update while update is in progress.
* @private
*/
@@ -73,14 +67,6 @@ cr.define('extensions', function() {
role: 'banner',
},
- /** @override */
- detached: function() {
- const openToastElement = this.$$('cr-toast[open]');
- if (openToastElement) {
- openToastElement.hide();
- }
- },
-
/**
* @return {boolean}
* @private
@@ -163,23 +149,20 @@ cr.define('extensions', function() {
}
this.isUpdating_ = true;
- const toastElement = this.$$('cr-toast');
- this.toastLabel_ = this.i18n('toolbarUpdatingToast');
+ const toastManager = cr.toastManager.getInstance();
// Keep the toast open indefinitely.
- toastElement.duration = 0;
- toastElement.show();
- this.delegate.updateAllExtensions()
- .then(() => {
- Polymer.IronA11yAnnouncer.requestAvailability();
- const doneText = this.i18n('toolbarUpdateDone');
- this.fire('iron-announce', {text: doneText});
- this.toastLabel_ = doneText;
- toastElement.show(3000);
+ toastManager.duration = 0;
+ toastManager.show(this.i18n('toolbarUpdatingToast'), false);
+ this.delegate.updateAllExtensions().then(
+ () => {
+ toastManager.hide();
+ toastManager.duration = 3000;
+ toastManager.show(this.i18n('toolbarUpdateDone'), false);
this.isUpdating_ = false;
- })
- .catch(function() {
- toastElement.hide();
+ },
+ () => {
+ toastManager.hide();
this.isUpdating_ = false;
});
},
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
index dc1a35b1729..7161b0893c1 100644
--- a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -6,7 +6,7 @@
// Note: webview_event_manager.js is already included by saml_handler.js.
/**
- * @fileoverview An UI component to authenciate to Chrome. The component hosts
+ * @fileoverview An UI component to authenticate to Chrome. The component hosts
* IdP web pages in a webview. A client who is interested in monitoring
* authentication events should subscribe itself via addEventListener(). After
* initialization, call {@code load} to start the authentication flow.
@@ -109,6 +109,12 @@ cr.define('cr.login', function() {
'email',
'readOnlyEmail',
'realm',
+ // If the authentication is done via external IdP, 'startsOnSamlPage'
+ // indicates whether the flow should start on the IdP page.
+ 'startsOnSamlPage',
+ // SAML assertion consumer URL, used to detect when Gaia-less SAML flows end
+ // (e.g. for SAML managed guest sessions).
+ 'samlAclUrl',
];
@@ -255,6 +261,7 @@ cr.define('cr.login', function() {
* @private
*/
this.isSamlUserPasswordless_ = null;
+ this.samlAclUrl_ = null;
window.addEventListener(
'message', this.onMessageFromWebview_.bind(this), false);
@@ -455,12 +462,23 @@ cr.define('cr.login', function() {
this.initialFrameUrl_ = this.constructInitialFrameUrl_(data);
this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_;
+ this.samlAclUrl_ = data.samlAclUrl;
+ // The email field is repurposed as public session email in SAML guest
+ // mode, ie when frameUrl is not empty.
+ if (data.samlAclUrl) {
+ this.email_ = data.email;
+ }
+
+ if (data.startsOnSamlPage) {
+ this.samlHandler_.startsOnSamlPage = true;
+ }
// Don't block insecure content for desktop flow because it lands on
// http. Otherwise, block insecure content as long as gaia is https.
this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP &&
this.idpOrigin_.startsWith('https://');
this.samlHandler_.extractSamlPasswordAttributes =
data.extractSamlPasswordAttributes;
+
this.needPassword = !('needPassword' in data) || data.needPassword;
this.webview_.contextMenus.onShow.addListener(function(e) {
@@ -578,6 +596,9 @@ cr.define('cr.login', function() {
if (data.ignoreCrOSIdpSetting === true) {
url = appendParam(url, 'ignoreCrOSIdpSetting', 'true');
}
+ if (data.enableGaiaActionButtons) {
+ url = appendParam(url, 'use_native_navigation', 1);
+ }
return url;
}
@@ -960,6 +981,7 @@ cr.define('cr.login', function() {
gaiaId: this.gaiaId_ || '',
password: this.password_ || '',
usingSAML: this.authFlow == AuthFlow.SAML,
+ publicSAML: this.samlAclUrl_ || false,
chooseWhatToSync: this.chooseWhatToSync_,
skipForNow: this.skipForNow_,
sessionIndex: this.sessionIndex_ || '',
@@ -1085,6 +1107,9 @@ cr.define('cr.login', function() {
this.webview_.focus();
} else if (currentUrl == BLANK_PAGE_URL) {
this.fireReadyEvent_();
+ } else if (currentUrl == this.samlAclUrl_) {
+ this.skipForNow_ = true;
+ this.onAuthCompleted_();
}
}
@@ -1094,7 +1119,7 @@ cr.define('cr.login', function() {
*/
onLoadAbort_(e) {
this.dispatchEvent(new CustomEvent(
- 'loadAbort', {detail: {error: e.reason, src: e.url}}));
+ 'loadAbort', {detail: {error_code: e.code, src: e.url}}));
}
/**
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js b/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js
index 4a1af059feb..789f6fec084 100644
--- a/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js
+++ b/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js
@@ -150,7 +150,7 @@ cr.define('cr.login', function() {
this.apiPasswordBytes_ = null;
/**
- * Whether to abort the authentication flow and show an error messagen
+ * Whether to abort the authentication flow and show an error message
* when content served over an unencrypted connection is detected.
* @type {boolean}
*/
@@ -282,6 +282,15 @@ cr.define('cr.login', function() {
}
/**
+ * Sets the startsOnSamlPage attribute of the SAML handler.
+ * @param {boolean} value
+ */
+ set startsOnSamlPage(value) {
+ this.startsOnSamlPage_ = value;
+ this.reset();
+ }
+
+ /**
* Removes the injected content script and unbinds all listeners from the
* webview passed to the constructor. This SAMLHandler will be unusable
* after this function returns.
diff --git a/chromium/chrome/browser/resources/hats/hats.html b/chromium/chrome/browser/resources/hats/hats.html
index 08793f12a1d..18ec74d79e5 100644
--- a/chromium/chrome/browser/resources/hats/hats.html
+++ b/chromium/chrome/browser/resources/hats/hats.html
@@ -1,30 +1,27 @@
+<!doctype html>
<html>
<head>
<style>
- /**
- * The style used to draw done-button.
- * Use z-index to make sure the button is in front of the survey content.
- * TODO(weili): we need to make it RTL friendly if we need to support RTL.
+ /* 402 is the project code name used in the content loaded by this page.
+ * We need to override their focus behavior to improve keyboard focus
+ * accessibility.
*/
- .done-button {
- bottom: 17px;
- color: rgb(33, 150, 243);
- display: block;
- font: 400 16px Roboto,RobotoDraft,Helvetica,sans-serif;
- position: fixed;
- right: 25px;
- text-transform: uppercase;
- z-index: 10;
+ .t402-prompt-websat .t402-prompt-root .t402-button:focus {
+ outline-style: auto;
}
-
- #id-done-button[hidden] {
- display: none;
+ .t402-css-theme-hats-material1 .t402-titlebar-title-alt:focus {
+ outline-style: auto;
+ }
+ :focus {
+ /* Needs to override dynamically loaded, more specific styles. */
+ outline-color: rgb(77, 144, 254) !important;
}
</style>
<script>
/**
- * Handles the callback when the survey is submitted or when the survey
- * has already been submitted in the past.
+ * Close the window when the survey is submitted or when the survey
+ * has already been submitted in the past. It is called through HaTS
+ * javascript library's accessGrantedCallback function.
* @param {boolean} isFirstRun Will be true when the user just earned
* access to the content and false if the user had already had access
* previously.
@@ -34,36 +31,49 @@
return;
}
- /* Display the done button at the end of the survey. */
- document.getElementById('id-done-button').hidden = false;
+ // HaTS 1 library will post the answer through a form to an iframe.
+ // Once the iframe is loaded, it will be disposed. We can not listen to
+ // the iframe's load event since the previous listener will dispose the
+ // iframe so our listener will not be notified. Instead, we listen to
+ // the iframe's disposal to make sure the iframe is already loaded,
+ // which means the answer has been posted to the server.
+ // TODO(weili): Once this issue is fixed in HaTS library
+ // (https://b.corp.google.com/issues/143494318), remove the following
+ // work around.
+ const element = document.querySelector(`iframe[id^='closure_frame']`);
+ if (element === null) {
+ // No iframe found.
+ window.close();
+ }
+
+ const observer = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutation) {
+ for (let i = 0; i < mutation.removedNodes.length; i++) {
+ if (element === mutation.removedNodes[i]) {
+ window.close();
+ }
+ }
+ })
+ });
- /* Auto dismiss after two seconds. */
- setTimeout(function(){ window.close(); }, 2000);
- };
+ // Watch for the iframe disposal event.
+ observer.observe(element.parentNode, {childList: true});
+ }
/**
* Called after the survey HTML is injected into the page.
+ * It is called through HaTS javascript library's afterShowCallback
+ * function.
*/
function onSurveyShown() {
- /* Don't show logo on the survey */
+ // Don't show logo on the survey.
const elements = document.getElementsByClassName('t402-prompt-logo');
for (const element of elements)
element.style.display = 'none';
}
-
- document.addEventListener('DOMContentLoaded', function() {
- document.getElementById('id-link-done-button').onclick = function() {
- window.close();
- }
- })
</script>
- <script src="$SCRIPT_SRC"></script>
+ <script src="$i18n{scriptSrc}"></script>
</head>
<body>
- <a id="id-link-done-button" href="#" role="button">
- <div id="id-done-button" class="done-button" hidden>
- $DONE_BUTTON_LABEL
- </div>
- </a>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/help_app/OWNERS b/chromium/chrome/browser/resources/help_app/OWNERS
index 925462999cb..8ccf6d7cd2f 100644
--- a/chromium/chrome/browser/resources/help_app/OWNERS
+++ b/chromium/chrome/browser/resources/help_app/OWNERS
@@ -1,4 +1,2 @@
achuith@chromium.org
-cnwan@chromium.org
-cylee@chromium.org
-davidyu@chromium.org
+carpenterr@chromium.org
diff --git a/chromium/chrome/browser/resources/history/constants.js b/chromium/chrome/browser/resources/history/constants.js
index cbf92a0697d..970d4001f0e 100644
--- a/chromium/chrome/browser/resources/history/constants.js
+++ b/chromium/chrome/browser/resources/history/constants.js
@@ -15,12 +15,16 @@ const BROWSING_GAP_TIME = 15 * 60 * 1000;
/**
* The largest bucket value for UMA histogram, based on entry ID. All entries
* with IDs greater than this will be included in this bucket.
+ * Keep consistent with the UMA constants on the Android history page
+ * (see HistoryManager.java).
* @type {number}
*/
const UMA_MAX_BUCKET_VALUE = 1000;
/**
* The largest bucket value for a UMA histogram that is a subset of above.
+ * Keep consistent with the UMA constants on the Android history page
+ * (see HistoryManager.java).
* @type {number}
*/
const UMA_MAX_SUBSET_BUCKET_VALUE = 100;
diff --git a/chromium/chrome/browser/resources/history/externs.js b/chromium/chrome/browser/resources/history/externs.js
index d772532ad2d..553d51d971e 100644
--- a/chromium/chrome/browser/resources/history/externs.js
+++ b/chromium/chrome/browser/resources/history/externs.js
@@ -12,6 +12,7 @@
* chrome/browser/ui/webui/browsing_history_handler.cc:
* BrowsingHistoryHandler::HistoryEntry::ToValue()
* @typedef {{allTimestamps: Array<number>,
+ * remoteIconUrlForUma: string,
* isUrlInRemoteUserData: boolean,
* blockedVisit: boolean,
* dateRelativeDay: string,
@@ -43,6 +44,7 @@ let HistoryQuery;
* The type of the foreign session tab object. This definition is based on
* chrome/browser/ui/webui/foreign_session_handler.cc:
* @typedef {{direction: string,
+ * remoteIconUrlForUma: string,
* sessionId: number,
* timestamp: number,
* title: string,
diff --git a/chromium/chrome/browser/resources/history/history_item.js b/chromium/chrome/browser/resources/history/history_item.js
index ad4a3f2a597..5d48e9220bc 100644
--- a/chromium/chrome/browser/resources/history/history_item.js
+++ b/chromium/chrome/browser/resources/history/history_item.js
@@ -234,15 +234,29 @@ cr.define('history', function() {
return;
}
+ const ageInDays = Math.ceil(
+ (new Date() - new Date(this.item.time)) / 1000 /* s/ms */ /
+ 60 /* m/s */ / 60 /* h/m */ / 24 /* d/h */);
+
browserService.recordHistogram(
'HistoryPage.ClickPosition',
Math.min(this.index, UMA_MAX_BUCKET_VALUE), UMA_MAX_BUCKET_VALUE);
+ browserService.recordHistogram(
+ 'HistoryPage.ClickAgeInDays',
+ Math.min(ageInDays, UMA_MAX_BUCKET_VALUE), UMA_MAX_BUCKET_VALUE);
+
if (this.index <= UMA_MAX_SUBSET_BUCKET_VALUE) {
browserService.recordHistogram(
'HistoryPage.ClickPositionSubset', this.index,
UMA_MAX_SUBSET_BUCKET_VALUE);
}
+
+ if (ageInDays <= UMA_MAX_SUBSET_BUCKET_VALUE) {
+ browserService.recordHistogram(
+ 'HistoryPage.ClickAgeInDaysSubset', ageInDays,
+ UMA_MAX_SUBSET_BUCKET_VALUE);
+ }
},
onLinkRightClick_: function() {
@@ -254,8 +268,9 @@ cr.define('history', function() {
* @private
*/
itemChanged_: function() {
- this.$.icon.style.backgroundImage =
- cr.icon.getFavicon(this.item.url, this.item.isUrlInRemoteUserData);
+ this.$.icon.style.backgroundImage = cr.icon.getFaviconForPageURL(
+ this.item.url, this.item.isUrlInRemoteUserData,
+ this.item.remoteIconUrlForUma);
this.listen(this.$['time-accessed'], 'mouseover', 'addTimeTitle_');
},
diff --git a/chromium/chrome/browser/resources/history/synced_device_card.js b/chromium/chrome/browser/resources/history/synced_device_card.js
index d1a1f8db25b..dbcb3ced83e 100644
--- a/chromium/chrome/browser/resources/history/synced_device_card.js
+++ b/chromium/chrome/browser/resources/history/synced_device_card.js
@@ -115,8 +115,8 @@ Polymer({
for (let i = 0; i < this.tabs.length; i++) {
// Entries on this UI are coming strictly from sync, so we can set
// |isSyncedUrlForHistoryUi| to true on the getFavicon call below.
- icons[i].style.backgroundImage =
- cr.icon.getFavicon(this.tabs[i].url, true);
+ icons[i].style.backgroundImage = cr.icon.getFaviconForPageURL(
+ this.tabs[i].url, true, this.tabs[i].remoteIconUrlForUma);
}
});
},
diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.css b/chromium/chrome/browser/resources/inline_login/inline_login.css
index a749a40f08e..dfbe238a01e 100644
--- a/chromium/chrome/browser/resources/inline_login/inline_login.css
+++ b/chromium/chrome/browser/resources/inline_login/inline_login.css
@@ -15,7 +15,7 @@ body,
#signin-frame,
#spinner-container {
- background-color: #f5f5f5;
+ background-color: var(--cr-card-background-color);
bottom: 0;
left: 0;
position: absolute;
@@ -24,9 +24,9 @@ body,
}
#spinner-container {
- -webkit-box-align: center;
- -webkit-box-pack: center;
- display: -webkit-box;
+ align-items: center;
+ display: flex;
+ justify-content: center;
}
#contents:not(.loading) #spinner-container {
@@ -34,13 +34,46 @@ body,
}
#navigation-button {
- --cr-icon-button-color: white;
- margin: 0;
+ background: white;
+ bottom: 32px;
+ left: 32px;
+ padding-inline-start: 10px;
position: absolute;
- top: 0;
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">
+#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 ab872711e2c..3bc61db7ddc 100644
--- a/chromium/chrome/browser/resources/inline_login/inline_login.html
+++ b/chromium/chrome/browser/resources/inline_login/inline_login.html
@@ -3,10 +3,12 @@
<head>
<title>$i18n{title}</title>
<link rel="import" href="chrome://resources/html/polymer.html">
- <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.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>
@@ -23,6 +25,12 @@
<div class="spinner"></div>
</div>
</div>
- <cr-icon-button id="navigation-button" iron-icon="cr:close"></cr-icon-button>
+
+ <cr-button
+ id="navigation-button"
+ aria-label="$i18n{accessibleBackButtonLabel}">
+ <iron-icon id="navigation-icon"></iron-icon>
+ $i18n{accessibleBackButtonLabel}
+ </cr-button>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.js b/chromium/chrome/browser/resources/inline_login/inline_login.js
index 5fde3c18ab5..98b6518a718 100644
--- a/chromium/chrome/browser/resources/inline_login/inline_login.js
+++ b/chromium/chrome/browser/resources/inline_login/inline_login.js
@@ -35,6 +35,7 @@ cr.define('inline.login', function() {
if (isLoginPrimaryAccount) {
chrome.send('metricsHandler:recordAction', ['Signin_SigninPage_Shown']);
}
+ chrome.send('authExtensionReady');
}
function onDropLink(e) {
@@ -65,6 +66,8 @@ cr.define('inline.login', function() {
*/
function initialize() {
$('navigation-button').addEventListener('click', navigationButtonClicked);
+ cr.addWebUIListener('showBackButton', showBackButton);
+ cr.addWebUIListener('navigateBackInWebview', navigateBackInWebview);
authExtHost = new cr.login.Authenticator('signin-frame');
authExtHost.addEventListener('dropLink', onDropLink);
authExtHost.addEventListener('ready', onAuthReady);
@@ -134,20 +137,17 @@ cr.define('inline.login', function() {
}
function showBackButton() {
- $('navigation-button').ironIcon =
- isRTL() ? 'cr:arrow-forward' : 'cr:arrow-back';
-
- $('navigation-button')
- .setAttribute(
- 'aria-label', loadTimeData.getString('accessibleBackButtonLabel'));
+ $('navigation-icon').icon =
+ isRTL() ? 'cr:chevron-right' : 'cr:chevron-left';
+ $('navigation-button').classList.add('enabled');
}
- function showCloseButton() {
- $('navigation-button').ironIcon = 'cr:close';
- $('navigation-button').classList.add('enabled');
- $('navigation-button')
- .setAttribute(
- 'aria-label', loadTimeData.getString('accessibleCloseButtonLabel'));
+ function navigateBackInWebview() {
+ if ($('signin-frame').canGoBack()) {
+ $('signin-frame').back();
+ } else {
+ closeDialog();
+ }
}
function navigationButtonClicked() {
@@ -164,7 +164,6 @@ cr.define('inline.login', function() {
loadAuthExtension: loadAuthExtension,
navigationButtonClicked: navigationButtonClicked,
showBackButton: showBackButton,
- showCloseButton: showCloseButton
};
});
diff --git a/chromium/chrome/browser/resources/local_discovery/local_discovery.js b/chromium/chrome/browser/resources/local_discovery/local_discovery.js
index 7094e5cec6b..1d2a54502cf 100644
--- a/chromium/chrome/browser/resources/local_discovery/local_discovery.js
+++ b/chromium/chrome/browser/resources/local_discovery/local_discovery.js
@@ -520,8 +520,7 @@ cr.define('local_discovery', function() {
function getOverlayIDFromPath() {
if (document.location.pathname == '/register') {
- const params = parseQueryParams(document.location);
- return params['id'] || null;
+ return new URL(document.location).searchParams.get('id');
}
}
diff --git a/chromium/chrome/browser/resources/local_ntp/BUILD.gn b/chromium/chrome/browser/resources/local_ntp/BUILD.gn
index 9b5c6384365..15edd04f0af 100644
--- a/chromium/chrome/browser/resources/local_ntp/BUILD.gn
+++ b/chromium/chrome/browser/resources/local_ntp/BUILD.gn
@@ -23,5 +23,8 @@ js_library("local_ntp") {
"utils.js",
"voice.js",
]
+ deps = [
+ "//ui/webui/resources/js:assert",
+ ]
externs_list = [ "externs.js" ]
}
diff --git a/chromium/chrome/browser/resources/local_ntp/customize.css b/chromium/chrome/browser/resources/local_ntp/customize.css
index 0022263c7be..ec345861118 100644
--- a/chromium/chrome/browser/resources/local_ntp/customize.css
+++ b/chromium/chrome/browser/resources/local_ntp/customize.css
@@ -95,6 +95,7 @@ html[dir=rtl] #edit-bg {
color: rgb(var(--GB600-rgb));
display: none;
font-size: 14px;
+ line-height: 1;
padding-inline-end: 12px;
padding-inline-start: 8px;
user-select: none;
@@ -286,7 +287,8 @@ html[dir=rtl] .bg-option-img {
box-shadow: 0 1px 3px 0 rgba(var(--GG800-rgb), .3),
0 4px 8px 3px rgba(var(--GG800-rgb), .15);
height: 400px;
- padding: 0 0 0 0;
+ max-height: 100vh; /* Constrain the dialog within viewport boundaries. */
+ padding: 0;
position: fixed;
top: 0;
/* Suitable for 3 columns of tiles on all platforms, accounting for larger
@@ -295,6 +297,13 @@ html[dir=rtl] .bg-option-img {
z-index: 10000;
}
+/* Prevent footer from overlapping with header at small window heights. */
+@media only screen and (max-height: 116px) {
+ #bg-sel-menu {
+ max-height: 116px;
+ }
+}
+
@media (prefers-color-scheme: dark) {
#bg-sel-menu {
background-color: rgb(var(--dark-mode-dialog-rgb));
@@ -312,6 +321,9 @@ right, so that every text can stay on its row even on the smallest window */
#bg-sel-tiles {
height: 284px;
+ /* Compress the tile section in order to constrain the dialog within viewport
+ * boundaries. 116px = 284px - (header + footer height) */
+ max-height: calc(100vh - 116px);
overflow-y: scroll;
padding-inline-start: 8px;
}
diff --git a/chromium/chrome/browser/resources/local_ntp/customize.js b/chromium/chrome/browser/resources/local_ntp/customize.js
index 658c6766a5f..ce243db2718 100644
--- a/chromium/chrome/browser/resources/local_ntp/customize.js
+++ b/chromium/chrome/browser/resources/local_ntp/customize.js
@@ -170,6 +170,7 @@ customize.CLASSES = {
COLLECTION_TILE: 'bg-sel-tile', // Preview tile for background customization
COLLECTION_TILE_BG: 'bg-sel-tile-bg',
COLLECTION_TITLE: 'bg-sel-tile-title', // Title of a background image
+ HIDDEN_SELECTED: 'hidden-selected',
IMAGE_DIALOG: 'is-img-sel',
ON_IMAGE_MENU: 'on-img-menu',
OPTION: 'bg-option',
@@ -328,8 +329,6 @@ customize.setMenuVisibility = function() {
$(customize.IDS.UPLOAD_IMAGE).hidden = false;
$(customize.IDS.RESTORE_DEFAULT).hidden = false;
$(customize.IDS.EDIT_BG_DIVIDER).hidden = false;
- $(customize.IDS.CUSTOM_LINKS_RESTORE_DEFAULT).hidden =
- configData.hideShortcuts;
$(customize.IDS.COLORS_BUTTON).hidden = !configData.chromeColors;
$(customize.IDS.COLOR_PICKER_CONTAINER)
.classList.toggle(
@@ -410,6 +409,9 @@ customize.clearAttribution = function() {
};
customize.unselectTile = function() {
+ if (configData.richerPicker) {
+ return;
+ }
$(customize.IDS.DONE).disabled = true;
customize.selectedOptions.background = null;
$(customize.IDS.DONE).tabIndex = -1;
@@ -736,13 +738,13 @@ customize.tileOnKeyDownInteraction = function(event) {
let target = null;
if (event.keyCode === customize.KEYCODES.LEFT) {
target = customize.getNextTile(
- document.documentElement.classList.contains('rtl') ? 1 : -1, 0,
+ window.chrome.embeddedSearch.searchBox.rtl ? 1 : -1, 0,
/** @type HTMLElement */ (tile));
} else if (event.keyCode === customize.KEYCODES.UP) {
target = customize.getNextTile(0, -1, /** @type HTMLElement */ (tile));
} else if (event.keyCode === customize.KEYCODES.RIGHT) {
target = customize.getNextTile(
- document.documentElement.classList.contains('rtl') ? -1 : 1, 0,
+ window.chrome.embeddedSearch.searchBox.rtl ? -1 : 1, 0,
/** @type HTMLElement */ (tile));
} else if (event.keyCode === customize.KEYCODES.DOWN) {
target = customize.getNextTile(0, 1, /** @type HTMLElement */ (tile));
@@ -976,10 +978,7 @@ customize.richerPicker_selectBackgroundTile = function(tile) {
return;
}
- $(customize.IDS.REFRESH_TOGGLE).checked = false;
-
- if (customize.selectedOptions.background &&
- customize.selectedOptions.background.id == tile.id) {
+ if (tile.parentElement.classList.contains(customize.CLASSES.SELECTED)) {
// If the clicked tile is already selected do nothing.
return;
} else if (customize.selectedOptions.background) {
@@ -988,6 +987,8 @@ customize.richerPicker_selectBackgroundTile = function(tile) {
customize.selectedOptions.background);
}
+ $(customize.IDS.REFRESH_TOGGLE).checked = false;
+
// Remove any existing preview.
customize.richerPicker_unpreviewImage();
@@ -1032,6 +1033,8 @@ customize.richerPicker_selectShortcutType = function(shortcutType) {
/**
* Handles hide shortcuts toggle. Apply/remove styling for the toggle and
* enable/disable the done button.
+ * Note: If the toggle is enabled, the options for shortcut type will appear
+ * "disabled".
* @param {boolean} areHidden True if the shortcuts are hidden, i.e. the toggle
* is on.
*/
@@ -1040,6 +1043,8 @@ customize.richerPicker_toggleShortcutHide = function(areHidden) {
$(customize.IDS.SHORTCUTS_HIDE)
.classList.toggle(customize.CLASSES.SELECTED, areHidden);
$(customize.IDS.SHORTCUTS_HIDE_TOGGLE).checked = areHidden;
+ $(customize.IDS.SHORTCUTS_MENU)
+ .classList.toggle(customize.CLASSES.HIDDEN_SELECTED, areHidden);
customize.selectedOptions.shortcutsAreHidden = areHidden;
};
@@ -1052,7 +1057,7 @@ customize.richerPicker_toggleRefreshDaily = function(toggledOn) {
$(customize.IDS.REFRESH_TOGGLE).checked = toggledOn;
if (!toggledOn) {
customize.richerPicker_selectBackgroundTile(
- $(customize.IDS.BACKGROUNDS_DEFAULT));
+ $(customize.IDS.BACKGROUNDS_DEFAULT_ICON));
return;
}
@@ -1061,6 +1066,7 @@ customize.richerPicker_toggleRefreshDaily = function(toggledOn) {
customize.selectedOptions.background);
}
+ customize.selectedOptions.background = null;
customize.selectedOptions.backgroundData = {
id: '',
url: '',
@@ -1200,7 +1206,7 @@ customize.showImageSelectionDialog = function(dialogTitle, collIndex) {
tileId = 'coll_' + collIndex + '_' + tileId;
}
const tile = customize.createTileThumbnail(
- tileId, collImg[i].imageUrl, dataset, tileOnClickInteraction,
+ tileId, collImg[i].thumbnailImageUrl, dataset, tileOnClickInteraction,
customize.tileOnKeyDownInteraction);
tile.setAttribute('aria-label', collImg[i].attributions[0]);
@@ -1422,7 +1428,7 @@ customize.richerPicker_preselectBackgroundOption = function() {
customize.preselectedOptions.backgroundsMenuTile = null;
- const themeInfo = ntpApiHandle.themeBackgroundInfo;
+ const themeInfo = assert(ntpApiHandle.themeBackgroundInfo);
if (!themeInfo.customBackgroundConfigured) {
// Default.
customize.preselectedOptions.backgroundsMenuTile =
@@ -1751,7 +1757,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
const restoreDefaultInteraction = function() {
editDialog.close();
customize.clearAttribution();
- window.chrome.embeddedSearch.newTabPage.setBackgroundURL('');
+ window.chrome.embeddedSearch.newTabPage.resetBackgroundInfo();
};
$(customize.IDS.RESTORE_DEFAULT).onclick = (event) => {
if (!$(customize.IDS.RESTORE_DEFAULT)
@@ -1931,6 +1937,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
$(customize.IDS.BACKGROUNDS_MENU).onkeydown = function(event) {
if (document.activeElement === $(customize.IDS.BACKGROUNDS_MENU) &&
customize.arrowKeys.includes(event.keyCode)) {
+ event.preventDefault();
$(customize.IDS.BACKGROUNDS_UPLOAD_ICON).focus();
}
};
@@ -1938,6 +1945,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
$(customize.IDS.BACKGROUNDS_IMAGE_MENU).onkeydown = function(event) {
if (document.activeElement === $(customize.IDS.BACKGROUNDS_IMAGE_MENU) &&
customize.arrowKeys.includes(event.keyCode)) {
+ event.preventDefault();
document.querySelector('[id$="img_tile_0"]').focus();
}
};
@@ -1970,7 +1978,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
};
const richerPicker = $(customize.IDS.CUSTOMIZATION_MENU);
- richerPicker.onclick = function(event) {
+ richerPicker.onmousedown = function(event) {
richerPicker.classList.add(customize.CLASSES.MOUSE_NAV);
};
richerPicker.onkeydown = function(event) {
@@ -2006,6 +2014,12 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
const clOption = $(customize.IDS.SHORTCUTS_OPTION_CUSTOM_LINKS);
const mvOption = $(customize.IDS.SHORTCUTS_OPTION_MOST_VISITED);
const hideToggle = $(customize.IDS.SHORTCUTS_HIDE_TOGGLE);
+
+ const rtl = window.chrome.embeddedSearch.searchBox.rtl;
+ const forwardArrowKey =
+ rtl ? customize.KEYCODES.LEFT : customize.KEYCODES.RIGHT;
+ const backArrowKey = rtl ? customize.KEYCODES.RIGHT : customize.KEYCODES.LEFT;
+
$(customize.IDS.SHORTCUTS_MENU).onkeydown = function(event) {
if (customize.arrowKeys.includes(event.keyCode)) {
clOption.focus();
@@ -2018,22 +2032,27 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
customize.LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_CUSTOM_LINKS_CLICKED);
}
customize.richerPicker_selectShortcutType(clOption);
+ // Selecting a shortcut type will turn off hidden shortcuts.
+ customize.richerPicker_toggleShortcutHide(false);
};
clOption.onkeydown = function(event) {
- if (event.keyCode === customize.KEYCODES.ENTER ||
- event.keyCode === customize.KEYCODES.SPACE) {
- clOption.click();
- } else if (customize.arrowKeys.includes(event.keyCode)) {
+ if (customize.arrowKeys.includes(event.keyCode)) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
- if (event.keyCode === customize.KEYCODES.RIGHT) {
+ if (event.keyCode === forwardArrowKey) {
mvOption.focus();
} else if (event.keyCode === customize.KEYCODES.DOWN) {
hideToggle.focus();
}
}
};
+ clOption.onkeyup = function(event) {
+ if (event.keyCode === customize.KEYCODES.ENTER ||
+ event.keyCode === customize.KEYCODES.SPACE) {
+ clOption.click();
+ }
+ };
mvOption.onclick = function() {
if (customize.selectedOptions.shortcutType !== mvOption) {
@@ -2041,24 +2060,29 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
customize.LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_MOST_VISITED_CLICKED);
}
customize.richerPicker_selectShortcutType(mvOption);
+ // Selecting a shortcut type will turn off hidden shortcuts.
+ customize.richerPicker_toggleShortcutHide(false);
};
mvOption.onkeydown = function(event) {
- if (event.keyCode === customize.KEYCODES.ENTER ||
- event.keyCode === customize.KEYCODES.SPACE) {
- mvOption.click();
- } else if (customize.arrowKeys.includes(event.keyCode)) {
+ if (customize.arrowKeys.includes(event.keyCode)) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
- if (event.keyCode === customize.KEYCODES.LEFT) {
+ if (event.keyCode === backArrowKey) {
clOption.focus();
} else if (
- event.keyCode === customize.KEYCODES.RIGHT ||
+ event.keyCode === forwardArrowKey ||
event.keyCode === customize.KEYCODES.DOWN) {
hideToggle.focus();
}
}
};
+ mvOption.onkeyup = function(event) {
+ if (event.keyCode === customize.KEYCODES.ENTER ||
+ event.keyCode === customize.KEYCODES.SPACE) {
+ mvOption.click();
+ }
+ };
hideToggle.onchange = function(event) {
customize.richerPicker_toggleShortcutHide(hideToggle.checked);
@@ -2066,19 +2090,22 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
customize.LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_VISIBILITY_TOGGLE_CLICKED);
};
hideToggle.onkeydown = function(event) {
- if (event.keyCode === customize.KEYCODES.ENTER ||
- event.keyCode === customize.KEYCODES.SPACE) {
- hideToggle.onchange(event);
- } else if (customize.arrowKeys.includes(event.keyCode)) {
+ if (customize.arrowKeys.includes(event.keyCode)) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
- if (event.keyCode === customize.KEYCODES.LEFT ||
+ if (event.keyCode === backArrowKey ||
event.keyCode === customize.KEYCODES.UP) {
mvOption.focus();
}
}
};
+ hideToggle.onkeyup = function(event) {
+ // Handle enter since, unlike space, it does not trigger a click event.
+ if (event.keyCode === customize.KEYCODES.ENTER) {
+ hideToggle.click();
+ }
+ };
hideToggle.onclick = function(event) {
// Enter and space fire the 'onclick' event (which will remove special
// keyboard navigation styling) unless propagation is stopped.
@@ -2091,10 +2118,10 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
customize.LOG_TYPE.NTP_BACKGROUND_REFRESH_TOGGLE_CLICKED);
customize.richerPicker_toggleRefreshDaily(refreshToggle.checked);
};
- refreshToggle.onkeydown = function(event) {
- if (event.keyCode === customize.KEYCODES.ENTER ||
- event.keyCode === customize.KEYCODES.SPACE) {
- refreshToggle.onchange(event);
+ refreshToggle.onkeyup = function(event) {
+ // Handle enter since, unlike space, it does not trigger a click event.
+ if (event.keyCode === customize.KEYCODES.ENTER) {
+ refreshToggle.click();
}
};
refreshToggle.onclick = function(event) {
@@ -2240,10 +2267,8 @@ customize.loadColorsMenu = function() {
const tile = customize.createTileWithoutTitle(
id, imageUrl, dataset, customize.colorTileInteraction,
customize.tileOnKeyDownInteraction);
- const label = configData.translatedStrings.colorLabelPrefix + ' ' +
- colorArrayToHex(colorsColl[i].color);
- tile.firstElementChild.setAttribute('aria-label', label);
- tile.firstElementChild.setAttribute('title', label);
+ tile.firstElementChild.setAttribute('aria-label', colorsColl[i].label);
+ tile.firstElementChild.setAttribute('title', colorsColl[i].label);
$(customize.IDS.COLORS_MENU).appendChild(tile);
}
@@ -2263,6 +2288,7 @@ customize.loadColorsMenu = function() {
} else {
$(customize.IDS.COLORS_DEFAULT_ICON).focus();
}
+ event.preventDefault();
}
};
@@ -2289,7 +2315,7 @@ customize.loadColorsMenu = function() {
*/
customize.colorsMenuOnThemeChange = function() {
// Update webstore theme information.
- const themeInfo = ntpApiHandle.themeBackgroundInfo;
+ const themeInfo = assert(ntpApiHandle.themeBackgroundInfo);
if (themeInfo.themeId && themeInfo.themeName) {
$(customize.IDS.COLORS_THEME).classList.add(customize.CLASSES.VISIBLE);
$(customize.IDS.COLORS_THEME_NAME).innerHTML = themeInfo.themeName;
@@ -2297,19 +2323,26 @@ customize.colorsMenuOnThemeChange = function() {
'https://chrome.google.com/webstore/detail/' + themeInfo.themeId;
$(customize.IDS.COLORS_THEME_UNINSTALL).onclick =
ntpApiHandle.useDefaultTheme;
+
+ // Clear the previous selection, if any.
+ if (customize.selectedOptions.color) {
+ customize.richerPicker_removeSelectedState(
+ customize.selectedOptions.color);
+ customize.selectedOptions.color = null;
+ }
} else {
$(customize.IDS.COLORS_THEME).classList.remove(customize.CLASSES.VISIBLE);
- }
- // Select the tile corresponding to the current theme/color.
- customize.colorsMenuPreselectTile();
+ // Select the tile corresponding to the current theme/color.
+ customize.colorsMenuPreselectTile();
+ }
};
/**
* Preselect Colors menu tile according to the theme info.
*/
customize.colorsMenuPreselectTile = function() {
- const themeInfo = ntpApiHandle.themeBackgroundInfo;
+ const themeInfo = assert(ntpApiHandle.themeBackgroundInfo);
let tile;
if (themeInfo.usingDefaultTheme) {
diff --git a/chromium/chrome/browser/resources/local_ntp/externs.js b/chromium/chrome/browser/resources/local_ntp/externs.js
index a520ad5e2e1..04feef1b03c 100644
--- a/chromium/chrome/browser/resources/local_ntp/externs.js
+++ b/chromium/chrome/browser/resources/local_ntp/externs.js
@@ -29,7 +29,6 @@ let MostVisitedData;
* @typedef {{chromeColors: boolean,
* enableShortcutsGrid: boolean,
* googleBaseUrl: string,
- * hideShortcuts: boolean,
* isAccessibleBrowser: boolean,
* isGooglePage: boolean,
* richerPicker: boolean,
@@ -290,9 +289,9 @@ window.chrome.embeddedSearch.newTabPage.searchSuggestionSelected;
window.chrome.embeddedSearch.newTabPage.selectLocalBackgroundImage;
/**
- * @param {string} background_url
+ * No params.
*/
-window.chrome.embeddedSearch.newTabPage.setBackgroundURL;
+window.chrome.embeddedSearch.newTabPage.resetBackgroundInfo;
/**
* @param {string} background_url
@@ -304,8 +303,38 @@ window.chrome.embeddedSearch.newTabPage.setBackgroundURL;
window.chrome.embeddedSearch.newTabPage.setBackgroundInfo;
/**
- * @return {Object} theme_background_info
- */
+ * @typedef {{
+ * alternateLogo: boolean,
+ * attribution1: (string|undefined),
+ * attribution2: (string|undefined),
+ * attributionActionUrl: (string|undefined),
+ * attributionUrl: (string|undefined),
+ * backgroundColorRgba: !Array<number>,
+ * collectionId: (string|undefined),
+ * colorDark: (!Array<number>|undefined),
+ * colorId: (number|undefined),
+ * colorLight: (!Array<number>|undefined),
+ * colorPicked: (!Array<number>|undefined),
+ * customBackgroundConfigured: boolean,
+ * iconBackgroundColor: !Array<number>,
+ * imageHorizontalAlignment: (string|undefined),
+ * imageTiling: (string|undefined),
+ * imageUrl: (string|undefined),
+ * imageVerticalAlignment: (string|undefined),
+ * isNtpBackgroundDark: boolean,
+ * logoColor: (!Array<number>|undefined),
+ * textColorLightRgba: !Array<number>,
+ * textColorRgba: !Array<number>,
+ * themeId: (string|undefined),
+ * themeName: (string|undefined),
+ * useTitleContainer: boolean,
+ * useWhiteAddIcon: boolean,
+ * usingDefaultTheme: boolean,
+ * }}
+ */
+let ThemeBackgroundInfo;
+
+/** @type {?ThemeBackgroundInfo} */
window.chrome.embeddedSearch.newTabPage.themeBackgroundInfo;
/**
@@ -352,6 +381,7 @@ window.chrome.embeddedSearch.newTabPage.updateCustomLink;
window.chrome.embeddedSearch.searchBox;
window.chrome.embeddedSearch.searchBox.isKeyCaptureEnabled;
window.chrome.embeddedSearch.searchBox.paste;
+window.chrome.embeddedSearch.searchBox.rtl;
window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes;
window.chrome.embeddedSearch.searchBox.stopCapturingKeyStrokes;
@@ -371,7 +401,6 @@ configData.translatedStrings.audioError;
configData.translatedStrings.backLabel;
configData.translatedStrings.backgroundsUnavailable;
configData.translatedStrings.clickToViewDoodle;
-configData.translatedStrings.colorLabelPrefix;
configData.translatedStrings.connectionError;
configData.translatedStrings.connectionErrorNoPeriod;
configData.translatedStrings.copyLink;
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.css b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
index ee6457ca9e8..206b5f9e96f 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
@@ -36,7 +36,6 @@ html {
/* These can be overridden by themes. */
--text-color: #000;
--text-color-light: #fff;
- --text-color-link: rgb(17, 85, 204);
height: 100%;
}
@@ -46,7 +45,6 @@ html {
/* These can be overridden by themes. */
--text-color: rgb(var(--GG200-rgb));
--text-color-light: rgb(var(--GG200-rgb));
- --text-color-link: rgb(var(--GB400-dark-rgb));
}
}
@@ -73,7 +71,7 @@ body {
min-height: 100%;
}
-body.inited {
+html.inited body {
display: block;
}
@@ -200,6 +198,7 @@ html[dir=rtl] #fakebox-search-icon {
text-align: initial;
text-overflow: ellipsis;
top: 0;
+ user-select: none;
vertical-align: middle;
visibility: inherit;
white-space: nowrap;
@@ -831,7 +830,7 @@ html[dir=rtl] .menu-option {
height: 32px;
line-height: 32px;
margin-inline-start: 16px;
- max-width: 126px;
+ max-width: 125px;
overflow: hidden;
text-overflow: ellipsis;
user-select: none;
@@ -892,6 +891,7 @@ html[dir=rtl] .menu-option {
margin-inline-start: 40px;
position: relative;
width: 568px;
+ z-index: 1;
}
.menu-panel {
@@ -1233,6 +1233,10 @@ html[dir=rtl] #customization-menu .bg-sel-tile .selected-check {
width: 268px;
}
+#shortcuts-menu.hidden-selected .sh-option {
+ color: rgb(var(--GG500-rgb));
+}
+
.sh-option-image {
border: 1px solid rgb(var(--GG300-rgb));
border-radius: 4px;
@@ -1249,13 +1253,13 @@ html[dir=rtl] #customization-menu .bg-sel-tile .selected-check {
}
}
-.selected .sh-option-image {
+#shortcuts-menu:not(.hidden-selected) .selected .sh-option-image {
background-color: rgb(var(--GB050-rgb));
border-color: rgb(var(--GB600-rgb));
}
@media (prefers-color-scheme: dark) {
- .selected .sh-option-image {
+ #shortcuts-menu:not(.hidden-selected) .selected .sh-option-image {
background-color: rgba(var(--GB200-rgb), .1);
border-color: rgb(var(--GB300-rgb));
}
@@ -1285,13 +1289,13 @@ html[dir=rtl] .sh-option-mini {
right: unset;
}
-.selected .sh-option-mini {
+#shortcuts-menu:not(.hidden-selected) .selected .sh-option-mini {
box-shadow: 0 1px 3px 0 rgba(var(--GG800-rgb), .3),
0 4px 8px 3px rgba(var(--GG800-rgb), .15);
}
@media (prefers-color-scheme: dark) {
- .selected .sh-option-mini {
+ #shortcuts-menu:not(.hidden-selected) .selected .sh-option-mini {
border-color: transparent;
box-shadow: var(--dark-mode-shadow);
}
@@ -1301,12 +1305,12 @@ html[dir=rtl] .sh-option-mini {
background-color: rgb(var(--GG500-rgb));
}
-.selected .sh-option-mini .mini-shortcuts {
+#shortcuts-menu:not(.hidden-selected) .selected .mini-shortcuts {
background-color: rgb(var(--GB600-rgb));
}
@media (prefers-color-scheme: dark) {
- .selected .sh-option-mini .mini-shortcuts {
+ #shortcuts-menu:not(.hidden-selected) .selected .mini-shortcuts {
background-color: rgb(var(--GB300-rgb));
}
}
@@ -1340,12 +1344,12 @@ html[dir=rtl] .sh-option-icon {
}
}
-.selected .sh-option-icon {
+#shortcuts-menu:not(.hidden-selected) .selected .sh-option-icon {
background-color: rgba(var(--GB600-rgb), .24);
}
@media (prefers-color-scheme: dark) {
- .selected .sh-option-icon {
+ #shortcuts-menu:not(.hidden-selected) .selected .sh-option-icon {
background-color: rgb(var(--GB300-rgb));
}
}
@@ -1375,6 +1379,11 @@ html[dir=rtl] .sh-option-image .selected-check {
right: initial;
}
+#shortcuts-menu.hidden-selected .sh-option-image
+ :-webkit-any(.selected-circle, .selected-check) {
+ display: none;
+}
+
.sh-option-title {
font-weight: bold;
margin: 8px 0;
@@ -1768,6 +1777,12 @@ html[dir=rtl] #left-semicircle {
border-top-right-radius: var(--tile-size);
}
+#colors-theme-info {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
#refresh-daily-wrapper {
display: none;
margin-inline-start: auto;
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.html b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
index f394f37fe88..0893eb63f94 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
@@ -14,6 +14,8 @@
$i18nRaw{bgPreloader}
<meta http-equiv="Content-Security-Policy"
content="$i18nRaw{contentSecurityPolicy}">
+ <script src="chrome-search://local-ntp/assert.js"
+ integrity="$i18n{assertIntegrity}"></script>
<script src="chrome-search://local-ntp/animations.js"
integrity="$i18n{animationsIntegrity}"></script>
<script src="chrome-search://local-ntp/config.js"
@@ -230,7 +232,7 @@
<div id="backgrounds-upload" class="bg-sel-tile-bg">
<div id="backgrounds-upload-icon" class="bg-sel-tile" tabindex="-1"
role="button" aria-label="$i18n{uploadImage}"
- title="$i18n{uploadImage}" aria-pressed="false">
+ aria-pressed="false" title="$i18n{uploadImage}">
<div id="backgrounds-upload-arrow"></div>
<div id="backgrounds-upload-text">$i18n{uploadImage}</div>
</div>
@@ -309,7 +311,7 @@
aria-label="$i18n{colorsOption}">
<div id="colors-theme" tabindex="0">
<div id="colors-theme-icon"></div>
- <div>
+ <div id="colors-theme-info">
<div id="colors-theme-name"></div>
$i18n{installedThemeDesc}
</div>
@@ -333,9 +335,10 @@
</div>
<div id="colors-default" class="bg-sel-tile-bg">
<div id="colors-default-icon" class="bg-sel-tile" tabindex="-1"
- aria-label="$i18n{defaultThemeLabel}"
- title="$i18n{defaultThemeLabel}"
- role="button" aria-pressed="false"></div>
+ aria-label="$i18n{defaultThemeLabel}"
+ title="$i18n{defaultThemeLabel}" tabindex="-1"
+ role="button" aria-pressed="false">
+ </div>
</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.js b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
index 0622671e086..21ebc4ef20f 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
@@ -6,13 +6,7 @@
* @fileoverview The local InstantExtended NTP.
*/
-/**
- * Whether the most visited tiles have finished loading, i.e. we've received the
- * 'loaded' postMessage from the iframe. Used by tests to detect that loading
- * has completed.
- * @type {boolean}
- */
-let tilesAreLoaded = false;
+// Global local statics (visible for testing).
/**
* Whether the Most Visited and edit custom link iframes should be created while
@@ -23,51 +17,21 @@ let tilesAreLoaded = false;
let iframesAndVoiceSearchDisabledForTesting = false;
/**
+ * Whether the most visited tiles have finished loading, i.e. we've received the
+ * 'loaded' postMessage from the iframe. Used by tests to detect that loading
+ * has completed.
+ * @type {boolean}
+ */
+let tilesAreLoaded = false;
+
+/**
* Controls rendering the new tab page for InstantExtended.
* @return {Object} A limited interface for testing the local NTP.
*/
function LocalNTP() {
'use strict';
-/**
- * Called by tests to disable the creation of Most Visited and edit custom link
- * iframes.
- */
-function disableIframesAndVoiceSearchForTesting() {
- iframesAndVoiceSearchDisabledForTesting = true;
-}
-
-/**
- * Specifications for an NTP design (not comprehensive).
- *
- * backgroundColor: The 4-component color of default background,
- * darkBackgroundColor: The 4-component color of default dark background,
- * iconBackgroundColor: The 4-component color of default dark icon background,
- * iconDarkBackgroundColor: The 4-component color of default icon background,
- * numTitleLines: Number of lines to display in titles.
- * titleColor: The 4-component color of title text.
- * titleColorAgainstDark: The 4-component color of title text against a dark
- * theme.
- *
- * @type {{
- * backgroundColor: Array<number>,
- * darkBackgroundColor: Array<number>,
- * iconBackgroundColor: Array<number>,
- * iconDarkBackgroundColor: Array<number>,
- * numTitleLines: number,
- * titleColor: Array<number>,
- * titleColorAgainstDark: Array<number>,
- * }}
- */
-const NTP_DESIGN = {
- backgroundColor: [255, 255, 255, 255],
- darkBackgroundColor: [50, 54, 57, 255],
- iconBackgroundColor: [241, 243, 244, 255], /** GG100 */
- iconDarkBackgroundColor: [32, 33, 36, 255], /** GG900 */
- numTitleLines: 1,
- titleColor: [60, 64, 67, 255], /** GG800 */
- titleColorAgainstDark: [248, 249, 250, 255], /** GG050 */
-};
+// Constants.
/**
* Enum for classnames.
@@ -107,6 +71,21 @@ const CLASSES = {
};
/**
+ * Background color for Chrome dark mode. Used to determine if it is possible to
+ * display a Google Doodle, or if the notifier should be used instead.
+ * @type {string}
+ * @const
+ */
+const DARK_MODE_BACKGROUND_COLOR = 'rgba(50,54,57,1)';
+
+/**
+ * The period of time (ms) before transitions can be applied to a toast
+ * notification after modifying the "display" property.
+ * @type {number}
+ */
+const DISPLAY_TIMEOUT = 20;
+
+/**
* Enum for HTML element ids.
* @enum {string}
* @const
@@ -165,6 +144,14 @@ const LOG_TYPE = {
};
/**
+ * The maximum number of tiles to show in the Most Visited section if custom
+ * links is enabled.
+ * @type {number}
+ * @const
+ */
+const MAX_NUM_TILES_CUSTOM_LINKS = 10;
+
+/**
* The maximum number of tiles to show in the Most Visited section.
* @type {number}
* @const
@@ -172,12 +159,42 @@ const LOG_TYPE = {
const MAX_NUM_TILES_MOST_VISITED = 8;
/**
- * The maximum number of tiles to show in the Most Visited section if custom
- * links is enabled.
+ * The period of time (ms) before the Most Visited notification is hidden.
* @type {number}
- * @const
*/
-const MAX_NUM_TILES_CUSTOM_LINKS = 10;
+const NOTIFICATION_TIMEOUT = 10000;
+
+/**
+ * Specifications for an NTP design (not comprehensive).
+ *
+ * backgroundColor: The 4-component color of default background,
+ * darkBackgroundColor: The 4-component color of default dark background,
+ * iconBackgroundColor: The 4-component color of default dark icon background,
+ * iconDarkBackgroundColor: The 4-component color of default icon background,
+ * numTitleLines: Number of lines to display in titles.
+ * titleColor: The 4-component color of title text.
+ * titleColorAgainstDark: The 4-component color of title text against a dark
+ * theme.
+ *
+ * @type {{
+ * backgroundColor: !Array<number>,
+ * darkBackgroundColor: !Array<number>,
+ * iconBackgroundColor: !Array<number>,
+ * iconDarkBackgroundColor: !Array<number>,
+ * numTitleLines: number,
+ * titleColor: !Array<number>,
+ * titleColorAgainstDark: !Array<number>,
+ * }}
+ */
+const NTP_DESIGN = {
+ backgroundColor: [255, 255, 255, 255],
+ darkBackgroundColor: [50, 54, 57, 255],
+ iconBackgroundColor: [241, 243, 244, 255], /** GG100 */
+ iconDarkBackgroundColor: [32, 33, 36, 255], /** GG900 */
+ numTitleLines: 1,
+ titleColor: [60, 64, 67, 255], /** GG800 */
+ titleColorAgainstDark: [248, 249, 250, 255], /** GG050 */
+};
/**
* Background colors considered "white". Used to determine if it is possible to
@@ -187,33 +204,27 @@ const MAX_NUM_TILES_CUSTOM_LINKS = 10;
*/
const WHITE_BACKGROUND_COLORS = ['rgba(255,255,255,1)', 'rgba(0,0,0,0)'];
-/**
- * Background color for Chrome dark mode. Used to determine if it is possible to
- * display a Google Doodle, or if the notifier should be used instead.
- * @type {string}
- * @const
- */
-const DARK_MODE_BACKGROUND_COLOR = 'rgba(50,54,57,1)';
+// Local statics.
/**
- * Enum for keycodes.
- * @enum {number}
- * @const
+ * The currently visible notification element. Null if no notification is
+ * present.
+ * @type {?Object}
*/
-const KEYCODE = {ENTER: 13, SPACE: 32};
+let currNotification = null;
/**
- * The period of time (ms) before the Most Visited notification is hidden.
- * @type {number}
+ * The timeout function for automatically hiding the pop-up notification. Only
+ * set if a notification is visible.
+ * @type {?Object}
*/
-const NOTIFICATION_TIMEOUT = 10000;
+let delayedHideNotification = null;
/**
- * The period of time (ms) before transitions can be applied to a toast
- * notification after modifying the "display" property.
- * @type {number}
+ * True if dark mode is enabled.
+ * @type {boolean}
*/
-const DISPLAY_TIMEOUT = 20;
+let isDarkModeEnabled = false;
/**
* The last blacklisted tile rid if any, which by definition should not be
@@ -223,30 +234,22 @@ const DISPLAY_TIMEOUT = 20;
let lastBlacklistedTile = null;
/**
- * The timeout function for automatically hiding the pop-up notification. Only
- * set if a notification is visible.
- * @type {?Object}
- */
-let delayedHideNotification = null;
-
-/**
- * The currently visible notification element. Null if no notification is
- * present.
- * @type {?Object}
- */
-let currNotification = null;
-
-/**
* The browser embeddedSearch.newTabPage object.
* @type {Object}
*/
let ntpApiHandle;
+// Helper methods.
+
/**
- * True if dark mode is enabled.
- * @type {boolean}
+ * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
+ * @param {Array<number>} color Array of rgba color components.
+ * @return {string} CSS color in RGBA format.
*/
-let isDarkModeEnabled = false;
+function convertToRGBAColor(color) {
+ return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' +
+ color[3] / 255 + ')';
+}
/**
* Returns a timeout that can be executed early. Calls back true if this was
@@ -270,419 +273,174 @@ function createExecutableTimeout(timeout, delay) {
};
}
-/**
- * Called by tests to override the executable timeout with a test timeout.
- * @param {!Function} timeout The timeout function. Requires a boolean param.
- */
-function overrideExecutableTimeoutForTesting(timeout) {
- createExecutableTimeout = timeout;
-}
-
-/**
- * Returns theme background info, first checking for history.state.notheme. If
- * the page has notheme set, returns a fallback light-colored theme (or dark-
- * colored theme if dark mode is enabled). This is used when the doodle is
- * displayed after clicking the notifier.
- */
-function getThemeBackgroundInfo() {
- if (history.state && history.state.notheme) {
- return {
- alternateLogo: false,
- backgroundColorRgba:
- (isDarkModeEnabled ? NTP_DESIGN.darkBackgroundColor :
- NTP_DESIGN.backgroundColor),
- customBackgroundConfigured: false,
- iconBackgroundColor:
- (isDarkModeEnabled ? NTP_DESIGN.iconDarkBackgroundColor :
- NTP_DESIGN.iconBackgroundColor),
- isNtpBackgroundDark: isDarkModeEnabled,
- textColorLightRgba: [102, 102, 102, 255],
- textColorRgba:
- (isDarkModeEnabled ? NTP_DESIGN.titleColorAgainstDark :
- NTP_DESIGN.titleColor),
- useTitleContainer: false,
- useWhiteAddIcon: isDarkModeEnabled,
- usingDarkMode: isDarkModeEnabled,
- usingDefaultTheme: true,
- };
- }
-
- const info = window.chrome.embeddedSearch.newTabPage.themeBackgroundInfo;
- const preview = $(customize.IDS.CUSTOM_BG_PREVIEW);
- if (preview.dataset.hasPreview === 'true') {
- info.isNtpBackgroundDark = preview.dataset.hasImage === 'true';
- info.customBackgroundConfigured = preview.dataset.hasImage === 'true';
- info.alternateLogo = preview.dataset.hasImage === 'true';
- // backgroundImage is in the form: url("actual url"). Remove everything
- // except the actual url.
- info.imageUrl = preview.style.backgroundImage.slice(5, -2);
- }
- return info;
-}
-
-/**
- * Determine whether dark chips should be used if dark mode is enabled. This is
- * is the case when dark mode is enabled and a background image (from a custom
- * background or user theme) is not set.
- *
- * @param {!Object} info Theme background information.
- * @return {boolean} Whether the chips should be dark.
- */
-function getUseDarkChips(info) {
- return window.matchMedia('(prefers-color-scheme: dark)').matches &&
- !info.imageUrl;
-}
-
-/**
- * Updates the NTP based on the current theme.
- */
-function renderTheme() {
- const info = getThemeBackgroundInfo();
- if (!info) {
- return;
- }
-
- $(IDS.NTP_CONTENTS).classList.toggle(CLASSES.DARK, info.isNtpBackgroundDark);
-
- // Update dark mode styling.
- isDarkModeEnabled = window.matchMedia('(prefers-color-scheme: dark)').matches;
- document.body.classList.toggle('light-chip', !getUseDarkChips(info));
+/** Create the Most Visited and edit custom links iframes. */
+function createIframes() {
+ // Collect arguments for the most visited iframe.
+ const args = [];
- const background = [
- convertToRGBAColor(info.backgroundColorRgba), info.imageUrl,
- info.imageTiling, info.imageHorizontalAlignment, info.imageVerticalAlignment
- ].join(' ').trim();
+ const searchboxApiHandle = window.chrome.embeddedSearch.searchBox;
- // If a custom background has been selected the image will be applied to the
- // custom-background element instead of the body.
- if (!info.customBackgroundConfigured) {
- document.body.style.background = background;
+ if (searchboxApiHandle.rtl) {
+ args.push('rtl=1');
}
-
- // Dark mode uses a white Google logo.
- const useWhiteLogo =
- info.alternateLogo || (info.usingDefaultTheme && isDarkModeEnabled);
- document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, useWhiteLogo);
- const isNonWhiteBackground = !WHITE_BACKGROUND_COLORS.includes(background);
- document.body.classList.toggle(CLASSES.NON_WHITE_BG, isNonWhiteBackground);
-
- if (info.logoColor) {
- document.body.style.setProperty(
- '--logo-color', convertToRGBAColor(info.logoColor));
+ if (NTP_DESIGN.numTitleLines > 1) {
+ args.push('ntl=' + NTP_DESIGN.numTitleLines);
}
- // The doodle notifier should be shown for non-default backgrounds. This
- // includes non-white backgrounds, excluding dark mode gray if dark mode is
- // enabled.
- const isDefaultBackground = WHITE_BACKGROUND_COLORS.includes(background) ||
- (isDarkModeEnabled && background === DARK_MODE_BACKGROUND_COLOR);
- document.body.classList.toggle(CLASSES.USE_NOTIFIER, !isDefaultBackground);
-
- updateThemeAttribution(info.attributionUrl, info.imageHorizontalAlignment);
- setCustomThemeStyle(info);
-
- if (info.customBackgroundConfigured) {
- // Do anything only if the custom background changed.
- if (!$(IDS.CUSTOM_BG).style.backgroundImage.includes(info.imageUrl)) {
- const imageWithOverlay = [
- customize.CUSTOM_BACKGROUND_OVERLAY, 'url(' + info.imageUrl + ')'
- ].join(',').trim();
- // If the theme update is because of uploading a local image then we
- // should close the customization menu. Closing the menu before the image
- // is selected doesn't look good.
- const localImageFileName = 'background.jpg';
- if (!configData.richerPicker &&
- imageWithOverlay.includes(localImageFileName) &&
- !$(IDS.CUSTOM_BG)
- .style.backgroundImage.includes(localImageFileName)) {
- customize.closeCustomizationDialog();
- }
- // |image| and |imageWithOverlay| use the same url as their source.
- // Waiting to display the custom background until |image| is fully
- // loaded ensures that |imageWithOverlay| is also loaded.
- $(IDS.CUSTOM_BG).style.backgroundImage = imageWithOverlay;
- const image = new Image();
- image.onload = function() {
- $(IDS.CUSTOM_BG).style.opacity = '1';
- };
- image.src = info.imageUrl;
+ args.push(
+ 'title=' +
+ encodeURIComponent(configData.translatedStrings.mostVisitedTitle));
+ args.push(
+ 'removeTooltip=' +
+ encodeURIComponent(configData.translatedStrings.removeThumbnailTooltip));
- customize.clearAttribution();
- customize.setAttribution(
- info.attribution1, info.attribution2, info.attributionActionUrl);
+ if (configData.isGooglePage) {
+ args.push('enableCustomLinks=1');
+ if (configData.enableShortcutsGrid) {
+ args.push('enableGrid=1');
}
- } else {
- $(IDS.CUSTOM_BG).style.opacity = '0';
- customize.clearAttribution();
+ args.push(
+ 'addLink=' +
+ encodeURIComponent(configData.translatedStrings.addLinkTitle));
+ args.push(
+ 'addLinkTooltip=' +
+ encodeURIComponent(configData.translatedStrings.addLinkTooltip));
+ args.push(
+ 'editLinkTooltip=' +
+ encodeURIComponent(configData.translatedStrings.editLinkTooltip));
}
- $(customize.IDS.RESTORE_DEFAULT)
- .classList.toggle(
- customize.CLASSES.OPTION_DISABLED, !info.customBackgroundConfigured);
- $(customize.IDS.RESTORE_DEFAULT).tabIndex =
- (info.customBackgroundConfigured ? 0 : -1);
+ // Create the most visited iframe.
+ const iframe = document.createElement('iframe');
+ iframe.id = IDS.TILES_IFRAME;
+ iframe.name = IDS.TILES_IFRAME;
+ iframe.title = configData.translatedStrings.mostVisitedTitle;
+ iframe.src = 'chrome-search://most-visited/single.html?' + args.join('&');
+ $(IDS.TILES).appendChild(iframe);
- $(customize.IDS.EDIT_BG)
- .classList.toggle(
- CLASSES.ENTRY_POINT_ENHANCED, !info.customBackgroundConfigured);
+ iframe.onload = function() {
+ sendThemeInfoToMostVisitedIframe();
+ reloadTiles();
+ };
if (configData.isGooglePage) {
- customize.onThemeChange();
- }
-}
-
-/**
- * Sends the current theme info to the most visited iframe.
- */
-function sendThemeInfoToMostVisitedIframe() {
- const info = getThemeBackgroundInfo();
- if (!info) {
- return;
- }
+ // Collect arguments for the edit custom link iframe.
+ const clArgs = [];
- const message = {cmd: 'updateTheme'};
- message.isThemeDark = info.isNtpBackgroundDark;
- message.customBackground = info.customBackgroundConfigured;
- message.useTitleContainer = info.useTitleContainer;
- message.iconBackgroundColor = convertToRGBAColor(info.iconBackgroundColor);
- message.useWhiteAddIcon = info.useWhiteAddIcon;
+ if (searchboxApiHandle.rtl) {
+ clArgs.push('rtl=1');
+ }
- let titleColor = NTP_DESIGN.titleColor;
- if (!info.usingDefaultTheme && info.textColorRgba) {
- titleColor = info.textColorRgba;
- } else if (info.isNtpBackgroundDark) {
- titleColor = NTP_DESIGN.titleColorAgainstDark;
- }
- message.tileTitleColor = convertToRGBAColor(titleColor);
+ clArgs.push(
+ 'addTitle=' +
+ encodeURIComponent(configData.translatedStrings.addLinkTitle));
+ clArgs.push(
+ 'editTitle=' +
+ encodeURIComponent(configData.translatedStrings.editLinkTitle));
+ clArgs.push(
+ 'nameField=' +
+ encodeURIComponent(configData.translatedStrings.nameField));
+ clArgs.push(
+ 'urlField=' +
+ encodeURIComponent(configData.translatedStrings.urlField));
+ clArgs.push(
+ 'linkRemove=' +
+ encodeURIComponent(configData.translatedStrings.linkRemove));
+ clArgs.push(
+ 'linkCancel=' +
+ encodeURIComponent(configData.translatedStrings.linkCancel));
+ clArgs.push(
+ 'linkDone=' +
+ encodeURIComponent(configData.translatedStrings.linkDone));
+ clArgs.push(
+ 'invalidUrl=' +
+ encodeURIComponent(configData.translatedStrings.invalidUrl));
- const iframe = $(IDS.TILES_IFRAME);
- if (iframe) {
- iframe.contentWindow.postMessage(message, '*');
+ // Create the edit custom link iframe.
+ const clIframe = document.createElement('iframe');
+ clIframe.id = IDS.CUSTOM_LINKS_EDIT_IFRAME;
+ clIframe.name = IDS.CUSTOM_LINKS_EDIT_IFRAME;
+ clIframe.title = configData.translatedStrings.editLinkTitle;
+ clIframe.src = 'chrome-search://most-visited/edit.html?' + clArgs.join('&');
+ const clIframeDialog = document.createElement('dialog');
+ clIframeDialog.id = IDS.CUSTOM_LINKS_EDIT_IFRAME_DIALOG;
+ clIframeDialog.classList.add(CLASSES.CUSTOMIZE_DIALOG);
+ clIframeDialog.appendChild(clIframe);
+ document.body.appendChild(clIframeDialog);
}
-}
-/**
- * Updates the OneGoogleBar (if it is loaded) based on the current theme.
- * TODO(crbug.com/918582): Add support for OGB dark mode.
- */
-function renderOneGoogleBarTheme() {
- if (!window.gbar) {
- return;
- }
- try {
- const oneGoogleBarApi = window.gbar.a;
- const oneGoogleBarPromise = oneGoogleBarApi.bf();
- oneGoogleBarPromise.then(function(oneGoogleBar) {
- const setForegroundStyle = oneGoogleBar.pc.bind(oneGoogleBar);
- setForegroundStyle(getThemeBackgroundInfo().isNtpBackgroundDark ? 1 : 0);
- });
- } catch (err) {
- console.log('Failed setting OneGoogleBar theme:\n' + err);
- }
+ window.addEventListener('message', handlePostMessage);
}
/**
- * Callback for embeddedSearch.newTabPage.onthemechange.
+ * Return true if custom links are enabled.
+ * @return {boolean}
*/
-function onThemeChange() {
- renderTheme();
- renderOneGoogleBarTheme();
- sendThemeInfoToMostVisitedIframe();
+function customLinksEnabled() {
+ return configData.isGooglePage &&
+ !chrome.embeddedSearch.newTabPage.isUsingMostVisited;
}
/**
- * Updates the NTP style according to theme.
- * @param {Object} themeInfo The information about the theme.
+ * Called by tests to disable the creation of Most Visited and edit custom link
+ * iframes.
*/
-function setCustomThemeStyle(themeInfo) {
- let textColor = '';
- let textColorLight = '';
- let mvxFilter = '';
- if (!themeInfo.usingDefaultTheme) {
- textColor = convertToRGBAColor(themeInfo.textColorRgba);
- textColorLight = convertToRGBAColor(themeInfo.textColorLightRgba);
- mvxFilter = 'drop-shadow(0 0 0 ' + textColor + ')';
- }
-
- $(IDS.NTP_CONTENTS)
- .classList.toggle(CLASSES.DEFAULT_THEME, themeInfo.usingDefaultTheme);
-
- document.body.style.setProperty('--text-color', textColor);
- document.body.style.setProperty('--text-color-light', textColorLight);
- // Themes reuse the "light" text color for links too.
- document.body.style.setProperty('--text-color-link', textColorLight);
+function disableIframesAndVoiceSearchForTesting() {
+ iframesAndVoiceSearchDisabledForTesting = true;
}
/**
- * Renders the attribution if the URL is present, otherwise hides it.
- * @param {string} url The URL of the attribution image, if any.
- * @param {string} themeBackgroundAlignment The alignment of the theme
- * background image. This is used to compute the attribution's alignment.
+ * Animates the pop-up notification to float down, and clears the timeout to
+ * hide the notification.
+ * @param {?Element} notification The notification element.
+ * @param {?Element} notificationContainer The notification container element.
+ * @param {boolean} showPromo Do show the promo if present.
*/
-function updateThemeAttribution(url, themeBackgroundAlignment) {
- if (!url) {
- setAttributionVisibility_(false);
+function floatDownNotification(notification, notificationContainer, showPromo) {
+ if (!notification || !notificationContainer) {
return;
}
- const attribution = $(IDS.ATTRIBUTION);
- let attributionImage = attribution.querySelector('img');
- if (!attributionImage) {
- attributionImage = new Image();
- attribution.appendChild(attributionImage);
- }
- attributionImage.style.content = url;
-
- // To avoid conflicts, place the attribution on the left for themes that
- // right align their background images.
- attribution.classList.toggle(
- CLASSES.LEFT_ALIGN_ATTRIBUTION, themeBackgroundAlignment == 'right');
- setAttributionVisibility_(true);
-}
-
-/**
- * Sets the visibility of the theme attribution.
- * @param {boolean} show True to show the attribution.
- */
-function setAttributionVisibility_(show) {
- $(IDS.ATTRIBUTION).style.display = show ? '' : 'none';
-}
-
-/**
- * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
- * @param {Array<number>} color Array of rgba color components.
- * @return {string} CSS color in RGBA format.
- */
-function convertToRGBAColor(color) {
- return 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' +
- color[3] / 255 + ')';
-}
-
-/**
- * Callback for embeddedSearch.newTabPage.onmostvisitedchange. Called when the
- * NTP tiles are updated.
- */
-function onMostVisitedChange() {
- reloadTiles();
-}
-
-/**
- * Fetches new data (RIDs) from the embeddedSearch.newTabPage API and passes
- * them to the iframe.
- */
-function reloadTiles() {
- // Don't attempt to load tiles if the MV data isn't available yet - this can
- // happen occasionally, see https://crbug.com/794942. In that case, we should
- // get an onMostVisitedChange call once they are available.
- // Note that MV data being available is different from having > 0 tiles. There
- // can legitimately be 0 tiles, e.g. if the user blacklisted them all.
- if (!ntpApiHandle.mostVisitedAvailable) {
+ if (!notificationContainer.classList.contains(CLASSES.FLOAT_UP)) {
return;
}
- const pages = ntpApiHandle.mostVisited;
- const cmds = [];
- const maxNumTiles = customLinksEnabled() ? MAX_NUM_TILES_CUSTOM_LINKS :
- MAX_NUM_TILES_MOST_VISITED;
- for (let i = 0; i < Math.min(maxNumTiles, pages.length); ++i) {
- cmds.push({cmd: 'tile', rid: pages[i].rid});
- }
- cmds.push({cmd: 'show'});
-
- const iframe = $(IDS.TILES_IFRAME);
- if (iframe) {
- iframe.contentWindow.postMessage(cmds, '*');
- }
-}
-
-/**
- * Callback for embeddedSearch.newTabPage.onaddcustomlinkdone. Called when the
- * custom link was successfully added. Shows the "Shortcut added" notification.
- * @param {boolean} success True if the link was successfully added.
- */
-function onAddCustomLinkDone(success) {
- if (success) {
- showNotification(configData.translatedStrings.linkAddedMsg);
- } else {
- showErrorNotification(
- configData.translatedStrings.linkCantCreate, null, null);
- }
- ntpApiHandle.logEvent(LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_DONE);
-}
-
-/**
- * Callback for embeddedSearch.newTabPage.onupdatecustomlinkdone. Called when
- * the custom link was successfully updated. Shows the "Shortcut edited"
- * notification.
- * @param {boolean} success True if the link was successfully updated.
- */
-function onUpdateCustomLinkDone(success) {
- if (success) {
- showNotification(configData.translatedStrings.linkEditedMsg);
- } else {
- showErrorNotification(
- configData.translatedStrings.linkCantEdit, null, null);
+ // Clear the timeout to hide the notification.
+ if (delayedHideNotification) {
+ delayedHideNotification.clear();
+ delayedHideNotification = null;
+ currNotification = null;
}
-}
-/**
- * Callback for embeddedSearch.newTabPage.ondeletecustomlinkdone. Called when
- * the custom link was successfully deleted. Shows the "Shortcut deleted"
- * notification.
- * @param {boolean} success True if the link was successfully deleted.
- */
-function onDeleteCustomLinkDone(success) {
- if (success) {
- showNotification(configData.translatedStrings.linkRemovedMsg);
- } else {
- showErrorNotification(
- configData.translatedStrings.linkCantRemove, null, null);
+ if (showPromo) {
+ // Show middle-slot promo if one is present.
+ const promo = $(IDS.PROMO);
+ if (promo) {
+ promo.classList.remove(CLASSES.HIDE_NOTIFICATION);
+ // Timeout is required for the "float" transition to work. Modifying the
+ // "display" property prevents transitions from activating for a brief
+ // period of time.
+ window.setTimeout(() => {
+ promo.classList.remove(CLASSES.FLOAT_DOWN);
+ }, DISPLAY_TIMEOUT);
+ }
}
-}
-/**
- * Shows the Most Visited pop-up notification and triggers a delay to hide it.
- * The message will be set to |msg|.
- * @param {string} msg The notification message.
- */
-function showNotification(msg) {
- $(IDS.NOTIFICATION_MESSAGE).textContent = msg;
- $(IDS.RESTORE_ALL_LINK).textContent = customLinksEnabled() ?
- configData.translatedStrings.restoreDefaultLinks :
- configData.translatedStrings.restoreThumbnailsShort;
- floatUpNotification($(IDS.NOTIFICATION), $(IDS.NOTIFICATION_CONTAINER));
- $(IDS.UNDO_LINK).focus();
-}
-
-/**
- * Hides the Most Visited pop-up notification.
- */
-function hideNotification() {
- floatDownNotification(
- $(IDS.NOTIFICATION), $(IDS.NOTIFICATION_CONTAINER), /*showPromo=*/ true);
-}
-
-/**
- * Shows the error pop-up notification and triggers a delay to hide it. The
- * message will be set to |msg|. If |linkName| and |linkOnClick| are present,
- * shows an error link with text set to |linkName| and onclick handled by
- * |linkOnClick|.
- * @param {string} msg The notification message.
- * @param {?string} linkName The error link text.
- * @param {?Function} linkOnClick The error link onclick handler.
- */
-function showErrorNotification(msg, linkName, linkOnClick) {
- const notification = $(IDS.ERROR_NOTIFICATION);
- $(IDS.ERROR_NOTIFICATION_MSG).textContent = msg;
- if (linkName && linkOnClick) {
- const notificationLink = $(IDS.ERROR_NOTIFICATION_LINK);
- notificationLink.textContent = linkName;
- notificationLink.onclick = linkOnClick;
- notification.classList.add(CLASSES.HAS_LINK);
- } else {
- notification.classList.remove(CLASSES.HAS_LINK);
- }
- floatUpNotification(notification, $(IDS.ERROR_NOTIFICATION_CONTAINER));
+ // Reset notification visibility once the animation is complete.
+ notificationContainer.addEventListener('transitionend', (event) => {
+ // Blur the hidden items.
+ $(IDS.UNDO_LINK).blur();
+ $(IDS.RESTORE_ALL_LINK).blur();
+ if (notification.classList.contains(CLASSES.HAS_LINK)) {
+ notification.classList.remove(CLASSES.HAS_LINK);
+ $(IDS.ERROR_NOTIFICATION_LINK).blur();
+ }
+ // Hide the notification
+ if (!notification.classList.contains(CLASSES.FLOAT_UP)) {
+ notification.classList.add(CLASSES.HIDE_NOTIFICATION);
+ }
+ }, {once: true});
+ notificationContainer.classList.remove(CLASSES.FLOAT_UP);
}
/**
@@ -741,168 +499,58 @@ function floatUpNotification(notification, notificationContainer) {
}
/**
- * Animates the pop-up notification to float down, and clears the timeout to
- * hide the notification.
- * @param {?Element} notification The notification element.
- * @param {?Element} notificationContainer The notification container element.
- * @param {boolean} showPromo Do show the promo if present.
- */
-function floatDownNotification(notification, notificationContainer, showPromo) {
- if (!notification || !notificationContainer) {
- return;
- }
-
- if (!notificationContainer.classList.contains(CLASSES.FLOAT_UP)) {
- return;
- }
-
- // Clear the timeout to hide the notification.
- if (delayedHideNotification) {
- delayedHideNotification.clear();
- delayedHideNotification = null;
- currNotification = null;
- }
-
- if (showPromo) {
- // Show middle-slot promo if one is present.
- const promo = $(IDS.PROMO);
- if (promo) {
- promo.classList.remove(CLASSES.HIDE_NOTIFICATION);
- // Timeout is required for the "float" transition to work. Modifying the
- // "display" property prevents transitions from activating for a brief
- // period of time.
- window.setTimeout(() => {
- promo.classList.remove(CLASSES.FLOAT_DOWN);
- }, DISPLAY_TIMEOUT);
- }
- }
-
- // Reset notification visibility once the animation is complete.
- notificationContainer.addEventListener('transitionend', (event) => {
- // Blur the hidden items.
- $(IDS.UNDO_LINK).blur();
- $(IDS.RESTORE_ALL_LINK).blur();
- if (notification.classList.contains(CLASSES.HAS_LINK)) {
- notification.classList.remove(CLASSES.HAS_LINK);
- $(IDS.ERROR_NOTIFICATION_LINK).blur();
- }
- // Hide the notification
- if (!notification.classList.contains(CLASSES.FLOAT_UP)) {
- notification.classList.add(CLASSES.HIDE_NOTIFICATION);
- }
- }, {once: true});
- notificationContainer.classList.remove(CLASSES.FLOAT_UP);
-}
-
-/**
- * Return true if custom links are enabled.
- * @return {boolean}
- */
-function customLinksEnabled() {
- return configData.isGooglePage &&
- !chrome.embeddedSearch.newTabPage.isUsingMostVisited;
-}
-
-/**
- * Handles a click on the notification undo link by hiding the notification and
- * informing Chrome.
- */
-function onUndo() {
- hideNotification();
- // Focus on the omnibox after the notification is hidden.
- window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes();
- if (customLinksEnabled()) {
- ntpApiHandle.undoCustomLinkAction();
- } else if (lastBlacklistedTile != null) {
- ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedTile);
- }
-}
-
-/**
- * Handles a click on the restore all notification link by hiding the
- * notification and informing Chrome.
+ * Returns theme background info, first checking for history.state.notheme. If
+ * the page has notheme set, returns a fallback light-colored theme (or dark-
+ * colored theme if dark mode is enabled). This is used when the doodle is
+ * displayed after clicking the notifier.
+ * @return {?ThemeBackgroundInfo}
*/
-function onRestoreAll() {
- hideNotification();
- // Focus on the omnibox after the notification is hidden.
- window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes();
- if (customLinksEnabled()) {
- ntpApiHandle.resetCustomLinks();
- } else {
- ntpApiHandle.undoAllMostVisitedDeletions();
+function getThemeBackgroundInfo() {
+ if (history.state && history.state.notheme) {
+ return {
+ alternateLogo: false,
+ backgroundColorRgba:
+ (isDarkModeEnabled ? NTP_DESIGN.darkBackgroundColor :
+ NTP_DESIGN.backgroundColor),
+ customBackgroundConfigured: false,
+ iconBackgroundColor:
+ (isDarkModeEnabled ? NTP_DESIGN.iconDarkBackgroundColor :
+ NTP_DESIGN.iconBackgroundColor),
+ isNtpBackgroundDark: isDarkModeEnabled,
+ textColorLightRgba: [102, 102, 102, 255],
+ textColorRgba:
+ (isDarkModeEnabled ? NTP_DESIGN.titleColorAgainstDark :
+ NTP_DESIGN.titleColor),
+ useTitleContainer: false,
+ useWhiteAddIcon: isDarkModeEnabled,
+ usingDefaultTheme: true,
+ };
}
-}
-/**
- * Callback for embeddedSearch.newTabPage.oninputstart. Handles new input by
- * disposing the NTP, according to where the input was entered.
- */
-function onInputStart() {
- if (isFakeboxFocused()) {
- setFakeboxFocus(false);
- setFakeboxDragFocus(false);
- setFakeboxVisibility(false);
+ const info = window.chrome.embeddedSearch.newTabPage.themeBackgroundInfo;
+ const preview = $(customize.IDS.CUSTOM_BG_PREVIEW);
+ if (preview.dataset.hasPreview === 'true') {
+ info.isNtpBackgroundDark = preview.dataset.hasImage === 'true';
+ info.customBackgroundConfigured = preview.dataset.hasImage === 'true';
+ info.alternateLogo = preview.dataset.hasImage === 'true';
+ // backgroundImage is in the form: url("actual url"). Remove everything
+ // except the actual url.
+ info.imageUrl = preview.style.backgroundImage.slice(5, -2);
}
+ return info;
}
/**
- * Callback for embeddedSearch.newTabPage.oninputcancel. Restores the NTP
- * (re-enables the fakebox and unhides the logo.)
- */
-function onInputCancel() {
- setFakeboxVisibility(true);
-}
-
-/**
- * @param {boolean} focus True to focus the fakebox.
- */
-function setFakeboxFocus(focus) {
- document.body.classList.toggle(CLASSES.FAKEBOX_FOCUS, focus);
-}
-
-/**
- * @param {boolean} focus True to show a dragging focus on the fakebox.
- */
-function setFakeboxDragFocus(focus) {
- document.body.classList.toggle(CLASSES.FAKEBOX_DRAG_FOCUS, focus);
-}
-
-/**
- * @return {boolean} True if the fakebox has focus.
- */
-function isFakeboxFocused() {
- return document.body.classList.contains(CLASSES.FAKEBOX_FOCUS) ||
- document.body.classList.contains(CLASSES.FAKEBOX_DRAG_FOCUS);
-}
-
-/**
- * @param {!Event} event The click event.
- * @return {boolean} True if the click occurred in an enabled fakebox.
- */
-function isFakeboxClick(event) {
- return $(IDS.FAKEBOX).contains(/** @type HTMLElement */ (event.target)) &&
- !$(IDS.FAKEBOX_MICROPHONE)
- .contains(/** @type HTMLElement */ (event.target));
-}
-
-/**
- * @param {boolean} show True to show the fakebox and logo.
- */
-function setFakeboxVisibility(show) {
- document.body.classList.toggle(CLASSES.HIDE_FAKEBOX, !show);
-}
-
-/**
- * @param {!Element} element The element to register the handler for.
- * @param {number} keycode The keycode of the key to register.
- * @param {!Function} handler The key handler to register.
+ * Determine whether dark chips should be used if dark mode is enabled. This is
+ * is the case when dark mode is enabled and a background image (from a custom
+ * background or user theme) is not set.
+ *
+ * @param {!Object} info Theme background information.
+ * @return {boolean} Whether the chips should be dark.
*/
-function registerKeyHandler(element, keycode, handler) {
- element.addEventListener('keydown', function(event) {
- if (event.keyCode == keycode) {
- handler(event);
- }
- });
+function getUseDarkChips(info) {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches &&
+ !info.imageUrl;
}
/**
@@ -923,7 +571,7 @@ function handlePostMessage(event) {
if ($(IDS.PROMO)) {
$(IDS.PROMO).classList.add(CLASSES.SHOW_ELEMENT);
}
- if (customLinksEnabled() && !configData.hideShortcuts) {
+ if (customLinksEnabled()) {
$(customize.IDS.CUSTOM_LINKS_RESTORE_DEFAULT)
.classList.toggle(
customize.CLASSES.OPTION_DISABLED, !args.showRestoreDefault);
@@ -963,43 +611,10 @@ function handlePostMessage(event) {
}
}
-/**
- * Request data for search suggestions, promo, and the OGB. Insert it into
- * the page once it's available. For search suggestions this should be almost
- * immediately as cached data is always used. Promos and the OGB may need
- * to wait for the asynchronous network request to complete.
- */
-function requestAndInsertGoogleResources() {
- if (!$('search-suggestions-loader')) {
- const ssScript = document.createElement('script');
- ssScript.id = 'search-suggestions-loader';
- ssScript.src = 'chrome-search://local-ntp/search-suggestions.js';
- ssScript.async = false;
- document.body.appendChild(ssScript);
- ssScript.onload = function() {
- injectSearchSuggestions(searchSuggestions);
- };
- }
- if (!$('one-google-loader')) {
- // Load the OneGoogleBar script. It'll create a global variable |og| which
- // is a JSON object corresponding to the native OneGoogleBarData type.
- const ogScript = document.createElement('script');
- ogScript.id = 'one-google-loader';
- ogScript.src = 'chrome-search://local-ntp/one-google.js';
- document.body.appendChild(ogScript);
- ogScript.onload = function() {
- injectOneGoogleBar(og);
- };
- }
- if (!$('promo-loader')) {
- const promoScript = document.createElement('script');
- promoScript.id = 'promo-loader';
- promoScript.src = 'chrome-search://local-ntp/promo.js';
- document.body.appendChild(promoScript);
- promoScript.onload = function() {
- injectPromo(promo);
- };
- }
+/** Hides the Most Visited pop-up notification. */
+function hideNotification() {
+ floatDownNotification(
+ $(IDS.NOTIFICATION), $(IDS.NOTIFICATION_CONTAINER), /*showPromo=*/ true);
}
/**
@@ -1025,14 +640,12 @@ function init() {
const undoLink = $(IDS.UNDO_LINK);
undoLink.addEventListener('click', onUndo);
- registerKeyHandler(undoLink, KEYCODE.ENTER, onUndo);
- registerKeyHandler(undoLink, KEYCODE.SPACE, onUndo);
+ registerKeyHandler(undoLink, ['Enter', ' '], onUndo);
undoLink.textContent = configData.translatedStrings.undoThumbnailRemove;
const restoreAllLink = $(IDS.RESTORE_ALL_LINK);
restoreAllLink.addEventListener('click', onRestoreAll);
- registerKeyHandler(restoreAllLink, KEYCODE.ENTER, onRestoreAll);
- registerKeyHandler(restoreAllLink, KEYCODE.SPACE, onRestoreAll);
+ registerKeyHandler(restoreAllLink, ['Enter', ' '], onRestoreAll);
$(IDS.ATTRIBUTION_TEXT).textContent =
configData.translatedStrings.attributionIntro;
@@ -1045,6 +658,8 @@ function init() {
renderTheme();
+ window.matchMedia('(prefers-color-scheme: dark)').onchange = onThemeChange;
+
const searchboxApiHandle = embeddedSearchApiHandle.searchBox;
if (configData.isGooglePage) {
@@ -1145,120 +760,46 @@ function init() {
utils.setPlatformClass(document.body);
utils.disableOutlineOnMouseClick($(customize.IDS.EDIT_BG));
- document.body.classList.add(CLASSES.INITED);
+ document.documentElement.classList.add(CLASSES.INITED);
}
/**
- * Create the Most Visited and edit custom links iframes.
+ * Injects the One Google Bar into the page. Called asynchronously, so that it
+ * doesn't block the main page load.
*/
-function createIframes() {
- // Collect arguments for the most visited iframe.
- const args = [];
-
- const searchboxApiHandle = window.chrome.embeddedSearch.searchBox;
-
- if (searchboxApiHandle.rtl) {
- args.push('rtl=1');
- }
- if (NTP_DESIGN.numTitleLines > 1) {
- args.push('ntl=' + NTP_DESIGN.numTitleLines);
- }
-
- args.push(
- 'title=' +
- encodeURIComponent(configData.translatedStrings.mostVisitedTitle));
- args.push(
- 'removeTooltip=' +
- encodeURIComponent(configData.translatedStrings.removeThumbnailTooltip));
-
- if (configData.isGooglePage) {
- args.push('enableCustomLinks=1');
- if (configData.enableShortcutsGrid) {
- args.push('enableGrid=1');
- }
- args.push(
- 'addLink=' +
- encodeURIComponent(configData.translatedStrings.addLinkTitle));
- args.push(
- 'addLinkTooltip=' +
- encodeURIComponent(configData.translatedStrings.addLinkTooltip));
- args.push(
- 'editLinkTooltip=' +
- encodeURIComponent(configData.translatedStrings.editLinkTooltip));
+function injectOneGoogleBar(ogb) {
+ if (ogb.barHtml === '') {
+ return;
}
- // Create the most visited iframe.
- const iframe = document.createElement('iframe');
- iframe.id = IDS.TILES_IFRAME;
- iframe.name = IDS.TILES_IFRAME;
- iframe.title = configData.translatedStrings.mostVisitedTitle;
- iframe.src = 'chrome-search://most-visited/single.html?' + args.join('&');
- $(IDS.TILES).appendChild(iframe);
-
- iframe.onload = function() {
- sendThemeInfoToMostVisitedIframe();
- reloadTiles();
- };
+ const inHeadStyle = document.createElement('style');
+ inHeadStyle.type = 'text/css';
+ inHeadStyle.appendChild(document.createTextNode(ogb.inHeadStyle));
+ document.head.appendChild(inHeadStyle);
- if (configData.isGooglePage) {
- // Collect arguments for the edit custom link iframe.
- const clArgs = [];
+ const inHeadScript = document.createElement('script');
+ inHeadScript.type = 'text/javascript';
+ inHeadScript.appendChild(document.createTextNode(ogb.inHeadScript));
+ document.head.appendChild(inHeadScript);
- if (searchboxApiHandle.rtl) {
- clArgs.push('rtl=1');
- }
+ renderOneGoogleBarTheme();
- clArgs.push(
- 'addTitle=' +
- encodeURIComponent(configData.translatedStrings.addLinkTitle));
- clArgs.push(
- 'editTitle=' +
- encodeURIComponent(configData.translatedStrings.editLinkTitle));
- clArgs.push(
- 'nameField=' +
- encodeURIComponent(configData.translatedStrings.nameField));
- clArgs.push(
- 'urlField=' +
- encodeURIComponent(configData.translatedStrings.urlField));
- clArgs.push(
- 'linkRemove=' +
- encodeURIComponent(configData.translatedStrings.linkRemove));
- clArgs.push(
- 'linkCancel=' +
- encodeURIComponent(configData.translatedStrings.linkCancel));
- clArgs.push(
- 'linkDone=' +
- encodeURIComponent(configData.translatedStrings.linkDone));
- clArgs.push(
- 'invalidUrl=' +
- encodeURIComponent(configData.translatedStrings.invalidUrl));
+ const ogElem = $('one-google');
+ ogElem.innerHTML = ogb.barHtml;
- // Create the edit custom link iframe.
- const clIframe = document.createElement('iframe');
- clIframe.id = IDS.CUSTOM_LINKS_EDIT_IFRAME;
- clIframe.name = IDS.CUSTOM_LINKS_EDIT_IFRAME;
- clIframe.title = configData.translatedStrings.editLinkTitle;
- clIframe.src = 'chrome-search://most-visited/edit.html?' + clArgs.join('&');
- const clIframeDialog = document.createElement('dialog');
- clIframeDialog.id = IDS.CUSTOM_LINKS_EDIT_IFRAME_DIALOG;
- clIframeDialog.classList.add(CLASSES.CUSTOMIZE_DIALOG);
- clIframeDialog.appendChild(clIframe);
- document.body.appendChild(clIframeDialog);
+ const afterBarScript = document.createElement('script');
+ afterBarScript.type = 'text/javascript';
+ afterBarScript.appendChild(document.createTextNode(ogb.afterBarScript));
+ ogElem.parentNode.insertBefore(afterBarScript, ogElem.nextSibling);
- if (configData.hideShortcuts) {
- $(IDS.TILES).style.display = 'none';
- clIframeDialog.style.display = 'none';
- }
- }
+ $('one-google-end-of-body').innerHTML = ogb.endOfBodyHtml;
- window.addEventListener('message', handlePostMessage);
-}
+ const endOfBodyScript = document.createElement('script');
+ endOfBodyScript.type = 'text/javascript';
+ endOfBodyScript.appendChild(document.createTextNode(ogb.endOfBodyScript));
+ document.body.appendChild(endOfBodyScript);
-/**
- * Binds event listeners.
- */
-function listen() {
- document.addEventListener('DOMContentLoaded', init);
+ ntpApiHandle.logEvent(LOG_TYPE.NTP_ONE_GOOGLE_BAR_SHOWN);
}
/**
@@ -1317,42 +858,488 @@ function injectSearchSuggestions(suggestions) {
}
/**
- * Injects the One Google Bar into the page. Called asynchronously, so that it
- * doesn't block the main page load.
+ * @param {!Event} event The click event.
+ * @return {boolean} True if the click occurred in an enabled fakebox.
*/
-function injectOneGoogleBar(ogb) {
- if (ogb.barHtml === '') {
- return;
+function isFakeboxClick(event) {
+ return $(IDS.FAKEBOX).contains(/** @type HTMLElement */ (event.target)) &&
+ !$(IDS.FAKEBOX_MICROPHONE)
+ .contains(/** @type HTMLElement */ (event.target));
+}
+
+/** @return {boolean} True if the fakebox has focus. */
+function isFakeboxFocused() {
+ return document.body.classList.contains(CLASSES.FAKEBOX_FOCUS) ||
+ document.body.classList.contains(CLASSES.FAKEBOX_DRAG_FOCUS);
+}
+
+/** Binds event listeners. */
+function listen() {
+ document.addEventListener('DOMContentLoaded', init);
+}
+
+/**
+ * Callback for embeddedSearch.newTabPage.onaddcustomlinkdone. Called when the
+ * custom link was successfully added. Shows the "Shortcut added" notification.
+ * @param {boolean} success True if the link was successfully added.
+ */
+function onAddCustomLinkDone(success) {
+ if (success) {
+ showNotification(configData.translatedStrings.linkAddedMsg);
+ } else {
+ showErrorNotification(
+ configData.translatedStrings.linkCantCreate, null, null);
}
+ ntpApiHandle.logEvent(LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_DONE);
+}
- const inHeadStyle = document.createElement('style');
- inHeadStyle.type = 'text/css';
- inHeadStyle.appendChild(document.createTextNode(ogb.inHeadStyle));
- document.head.appendChild(inHeadStyle);
+/**
+ * Callback for embeddedSearch.newTabPage.ondeletecustomlinkdone. Called when
+ * the custom link was successfully deleted. Shows the "Shortcut deleted"
+ * notification.
+ * @param {boolean} success True if the link was successfully deleted.
+ */
+function onDeleteCustomLinkDone(success) {
+ if (success) {
+ showNotification(configData.translatedStrings.linkRemovedMsg);
+ } else {
+ showErrorNotification(
+ configData.translatedStrings.linkCantRemove, null, null);
+ }
+}
- const inHeadScript = document.createElement('script');
- inHeadScript.type = 'text/javascript';
- inHeadScript.appendChild(document.createTextNode(ogb.inHeadScript));
- document.head.appendChild(inHeadScript);
+/**
+ * Callback for embeddedSearch.newTabPage.oninputcancel. Restores the NTP
+ * (re-enables the fakebox and unhides the logo.)
+ */
+function onInputCancel() {
+ setFakeboxVisibility(true);
+}
+/**
+ * Callback for embeddedSearch.newTabPage.oninputstart. Handles new input by
+ * disposing the NTP, according to where the input was entered.
+ */
+function onInputStart() {
+ if (isFakeboxFocused()) {
+ setFakeboxFocus(false);
+ setFakeboxDragFocus(false);
+ setFakeboxVisibility(false);
+ }
+}
+
+/**
+ * Callback for embeddedSearch.newTabPage.onmostvisitedchange. Called when the
+ * NTP tiles are updated.
+ */
+function onMostVisitedChange() {
+ reloadTiles();
+}
+
+/**
+ * Handles a click on the restore all notification link by hiding the
+ * notification and informing Chrome.
+ */
+function onRestoreAll() {
+ hideNotification();
+ // Focus on the omnibox after the notification is hidden.
+ window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes();
+ if (customLinksEnabled()) {
+ ntpApiHandle.resetCustomLinks();
+ } else {
+ ntpApiHandle.undoAllMostVisitedDeletions();
+ }
+}
+
+/**
+ * Callback for embeddedSearch.newTabPage.onthemechange.
+ */
+function onThemeChange() {
+ renderTheme();
renderOneGoogleBarTheme();
+ sendThemeInfoToMostVisitedIframe();
+}
- const ogElem = $('one-google');
- ogElem.innerHTML = ogb.barHtml;
+/**
+ * Handles a click on the notification undo link by hiding the notification and
+ * informing Chrome.
+ */
+function onUndo() {
+ hideNotification();
+ // Focus on the omnibox after the notification is hidden.
+ window.chrome.embeddedSearch.searchBox.startCapturingKeyStrokes();
+ if (customLinksEnabled()) {
+ ntpApiHandle.undoCustomLinkAction();
+ } else if (lastBlacklistedTile != null) {
+ ntpApiHandle.undoMostVisitedDeletion(lastBlacklistedTile);
+ }
+}
- const afterBarScript = document.createElement('script');
- afterBarScript.type = 'text/javascript';
- afterBarScript.appendChild(document.createTextNode(ogb.afterBarScript));
- ogElem.parentNode.insertBefore(afterBarScript, ogElem.nextSibling);
+/**
+ * Callback for embeddedSearch.newTabPage.onupdatecustomlinkdone. Called when
+ * the custom link was successfully updated. Shows the "Shortcut edited"
+ * notification.
+ * @param {boolean} success True if the link was successfully updated.
+ */
+function onUpdateCustomLinkDone(success) {
+ if (success) {
+ showNotification(configData.translatedStrings.linkEditedMsg);
+ } else {
+ showErrorNotification(
+ configData.translatedStrings.linkCantEdit, null, null);
+ }
+}
- $('one-google-end-of-body').innerHTML = ogb.endOfBodyHtml;
+/**
+ * Called by tests to override the executable timeout with a test timeout.
+ * @param {!Function} timeout The timeout function. Requires a boolean param.
+ */
+function overrideExecutableTimeoutForTesting(timeout) {
+ createExecutableTimeout = timeout;
+}
- const endOfBodyScript = document.createElement('script');
- endOfBodyScript.type = 'text/javascript';
- endOfBodyScript.appendChild(document.createTextNode(ogb.endOfBodyScript));
- document.body.appendChild(endOfBodyScript);
+/**
+ * @param {!Element} element
+ * @param {!Array<string>} keys
+ * @param {!function(Event)} handler
+ */
+function registerKeyHandler(element, keys, handler) {
+ element.addEventListener('keydown', e => {
+ if (keys.includes(e.key)) {
+ handler(e);
+ }
+ });
+}
- ntpApiHandle.logEvent(LOG_TYPE.NTP_ONE_GOOGLE_BAR_SHOWN);
+/**
+ * Fetches new data (RIDs) from the embeddedSearch.newTabPage API and passes
+ * them to the iframe.
+ */
+function reloadTiles() {
+ // Don't attempt to load tiles if the MV data isn't available yet - this can
+ // happen occasionally, see https://crbug.com/794942. In that case, we should
+ // get an onMostVisitedChange call once they are available.
+ // Note that MV data being available is different from having > 0 tiles. There
+ // can legitimately be 0 tiles, e.g. if the user blacklisted them all.
+ if (!ntpApiHandle.mostVisitedAvailable) {
+ return;
+ }
+
+ const pages = ntpApiHandle.mostVisited;
+ const cmds = [];
+ const maxNumTiles = customLinksEnabled() ? MAX_NUM_TILES_CUSTOM_LINKS :
+ MAX_NUM_TILES_MOST_VISITED;
+ for (let i = 0; i < Math.min(maxNumTiles, pages.length); ++i) {
+ cmds.push({cmd: 'tile', rid: pages[i].rid});
+ }
+ cmds.push({cmd: 'show'});
+
+ $(IDS.MOST_VISITED).hidden =
+ !chrome.embeddedSearch.newTabPage.areShortcutsVisible;
+
+ const iframe = $(IDS.TILES_IFRAME);
+ if (iframe) {
+ iframe.contentWindow.postMessage(cmds, '*');
+ }
+}
+
+/**
+ * Updates the OneGoogleBar (if it is loaded) based on the current theme.
+ * TODO(crbug.com/918582): Add support for OGB dark mode.
+ */
+function renderOneGoogleBarTheme() {
+ if (!window.gbar) {
+ return;
+ }
+ try {
+ const oneGoogleBarApi = window.gbar.a;
+ const oneGoogleBarPromise = oneGoogleBarApi.bf();
+ oneGoogleBarPromise.then(function(oneGoogleBar) {
+ const setForegroundStyle = oneGoogleBar.pc.bind(oneGoogleBar);
+ const themeInfo = getThemeBackgroundInfo();
+ setForegroundStyle(themeInfo && themeInfo.isNtpBackgroundDark ? 1 : 0);
+ });
+ } catch (err) {
+ console.log('Failed setting OneGoogleBar theme:\n' + err);
+ }
+}
+
+/** Updates the NTP based on the current theme. */
+function renderTheme() {
+ const info = getThemeBackgroundInfo();
+ if (!info) {
+ return;
+ }
+
+ $(IDS.NTP_CONTENTS).classList.toggle(CLASSES.DARK, info.isNtpBackgroundDark);
+
+ // Update dark mode styling.
+ isDarkModeEnabled = window.matchMedia('(prefers-color-scheme: dark)').matches;
+ document.body.classList.toggle('light-chip', !getUseDarkChips(info));
+
+ const background = [
+ convertToRGBAColor(info.backgroundColorRgba), info.imageUrl,
+ info.imageTiling, info.imageHorizontalAlignment, info.imageVerticalAlignment
+ ].join(' ').trim();
+
+ // If a custom background has been selected the image will be applied to the
+ // custom-background element instead of the body.
+ if (!info.customBackgroundConfigured) {
+ document.body.style.background = background;
+ }
+
+ // Dark mode uses a white Google logo.
+ const useWhiteLogo =
+ info.alternateLogo || (info.usingDefaultTheme && isDarkModeEnabled);
+ document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, useWhiteLogo);
+ const isNonWhiteBackground = !WHITE_BACKGROUND_COLORS.includes(background);
+ document.body.classList.toggle(CLASSES.NON_WHITE_BG, isNonWhiteBackground);
+
+ if (info.logoColor) {
+ document.body.style.setProperty(
+ '--logo-color', convertToRGBAColor(info.logoColor));
+ }
+
+ // The doodle notifier should be shown for non-default backgrounds. This
+ // includes non-white backgrounds, excluding dark mode gray if dark mode is
+ // enabled.
+ const isDefaultBackground = WHITE_BACKGROUND_COLORS.includes(background) ||
+ (isDarkModeEnabled && background === DARK_MODE_BACKGROUND_COLOR);
+ document.body.classList.toggle(CLASSES.USE_NOTIFIER, !isDefaultBackground);
+
+ updateThemeAttribution(info.attributionUrl, info.imageHorizontalAlignment);
+ setCustomThemeStyle(info);
+
+ if (info.customBackgroundConfigured) {
+ // Do anything only if the custom background changed.
+ const imageUrl = assert(info.imageUrl);
+ if (!$(IDS.CUSTOM_BG).style.backgroundImage.includes(imageUrl)) {
+ const imageWithOverlay = [
+ customize.CUSTOM_BACKGROUND_OVERLAY, 'url(' + imageUrl + ')'
+ ].join(',').trim();
+ // If the theme update is because of uploading a local image then we
+ // should close the customization menu. Closing the menu before the image
+ // is selected doesn't look good.
+ const localImageFileName = 'background.jpg';
+ if (!configData.richerPicker &&
+ imageWithOverlay.includes(localImageFileName)) {
+ customize.closeCustomizationDialog();
+ }
+ // |image| and |imageWithOverlay| use the same url as their source.
+ // Waiting to display the custom background until |image| is fully
+ // loaded ensures that |imageWithOverlay| is also loaded.
+ $(IDS.CUSTOM_BG).style.backgroundImage = imageWithOverlay;
+ const image = new Image();
+ image.onload = function() {
+ $(IDS.CUSTOM_BG).style.opacity = '1';
+ };
+ image.src = imageUrl;
+
+ customize.clearAttribution();
+ customize.setAttribution(
+ '' + info.attribution1, '' + info.attribution2,
+ '' + info.attributionActionUrl);
+ }
+ } else {
+ $(IDS.CUSTOM_BG).style.opacity = '0';
+ $(IDS.CUSTOM_BG).style.backgroundImage = '';
+ customize.clearAttribution();
+ }
+
+ $(customize.IDS.RESTORE_DEFAULT)
+ .classList.toggle(
+ customize.CLASSES.OPTION_DISABLED, !info.customBackgroundConfigured);
+ $(customize.IDS.RESTORE_DEFAULT).tabIndex =
+ (info.customBackgroundConfigured ? 0 : -1);
+
+ $(customize.IDS.EDIT_BG)
+ .classList.toggle(
+ CLASSES.ENTRY_POINT_ENHANCED, !info.customBackgroundConfigured);
+
+ if (configData.isGooglePage) {
+ customize.onThemeChange();
+ }
+}
+
+/**
+ * Request data for search suggestions, promo, and the OGB. Insert it into
+ * the page once it's available. For search suggestions this should be almost
+ * immediately as cached data is always used. Promos and the OGB may need
+ * to wait for the asynchronous network request to complete.
+ */
+function requestAndInsertGoogleResources() {
+ if (!$('search-suggestions-loader')) {
+ const ssScript = document.createElement('script');
+ ssScript.id = 'search-suggestions-loader';
+ ssScript.src = 'chrome-search://local-ntp/search-suggestions.js';
+ ssScript.async = false;
+ document.body.appendChild(ssScript);
+ ssScript.onload = function() {
+ injectSearchSuggestions(searchSuggestions);
+ };
+ }
+ if (!$('one-google-loader')) {
+ // Load the OneGoogleBar script. It'll create a global variable |og| which
+ // is a JSON object corresponding to the native OneGoogleBarData type.
+ const ogScript = document.createElement('script');
+ ogScript.id = 'one-google-loader';
+ ogScript.src = 'chrome-search://local-ntp/one-google.js';
+ document.body.appendChild(ogScript);
+ ogScript.onload = function() {
+ injectOneGoogleBar(og);
+ };
+ }
+ if (!$('promo-loader')) {
+ const promoScript = document.createElement('script');
+ promoScript.id = 'promo-loader';
+ promoScript.src = 'chrome-search://local-ntp/promo.js';
+ document.body.appendChild(promoScript);
+ promoScript.onload = function() {
+ injectPromo(promo);
+ };
+ }
+}
+
+/** Sends the current theme info to the most visited iframe. */
+function sendThemeInfoToMostVisitedIframe() {
+ const info = getThemeBackgroundInfo();
+ if (!info) {
+ return;
+ }
+
+ const message = {cmd: 'updateTheme'};
+ message.isThemeDark = info.isNtpBackgroundDark;
+ message.customBackground = info.customBackgroundConfigured;
+ message.useTitleContainer = info.useTitleContainer;
+ message.iconBackgroundColor = convertToRGBAColor(info.iconBackgroundColor);
+ message.useWhiteAddIcon = info.useWhiteAddIcon;
+
+ let titleColor = NTP_DESIGN.titleColor;
+ if (!info.usingDefaultTheme && info.textColorRgba) {
+ titleColor = info.textColorRgba;
+ } else if (info.isNtpBackgroundDark) {
+ titleColor = NTP_DESIGN.titleColorAgainstDark;
+ }
+ message.tileTitleColor = convertToRGBAColor(titleColor);
+
+ const iframe = $(IDS.TILES_IFRAME);
+ if (iframe) {
+ iframe.contentWindow.postMessage(message, '*');
+ }
+}
+
+/**
+ * Sets the visibility of the theme attribution.
+ * @param {boolean} show True to show the attribution.
+ */
+function setAttributionVisibility(show) {
+ $(IDS.ATTRIBUTION).style.display = show ? '' : 'none';
+}
+
+/**
+ * Updates the NTP style according to theme.
+ * @param {Object} themeInfo The information about the theme.
+ */
+function setCustomThemeStyle(themeInfo) {
+ let textColor = '';
+ let textColorLight = '';
+ let mvxFilter = '';
+ if (!themeInfo.usingDefaultTheme) {
+ textColor = convertToRGBAColor(themeInfo.textColorRgba);
+ textColorLight = convertToRGBAColor(themeInfo.textColorLightRgba);
+ mvxFilter = 'drop-shadow(0 0 0 ' + textColor + ')';
+ }
+
+ $(IDS.NTP_CONTENTS)
+ .classList.toggle(CLASSES.DEFAULT_THEME, themeInfo.usingDefaultTheme);
+
+ document.body.style.setProperty('--text-color', textColor);
+ document.body.style.setProperty('--text-color-light', textColorLight);
+}
+
+/**
+ * @param {boolean} focus True to show a dragging focus on the fakebox.
+ */
+function setFakeboxDragFocus(focus) {
+ document.body.classList.toggle(CLASSES.FAKEBOX_DRAG_FOCUS, focus);
+}
+
+/**
+ * @param {boolean} focus True to focus the fakebox.
+ */
+function setFakeboxFocus(focus) {
+ document.body.classList.toggle(CLASSES.FAKEBOX_FOCUS, focus);
+}
+
+/**
+ * @param {boolean} show True to show the fakebox and logo.
+ */
+function setFakeboxVisibility(show) {
+ document.body.classList.toggle(CLASSES.HIDE_FAKEBOX, !show);
+}
+
+/**
+ * Shows the error pop-up notification and triggers a delay to hide it. The
+ * message will be set to |msg|. If |linkName| and |linkOnClick| are present,
+ * shows an error link with text set to |linkName| and onclick handled by
+ * |linkOnClick|.
+ * @param {string} msg The notification message.
+ * @param {?string} linkName The error link text.
+ * @param {?Function} linkOnClick The error link onclick handler.
+ */
+function showErrorNotification(msg, linkName, linkOnClick) {
+ const notification = $(IDS.ERROR_NOTIFICATION);
+ $(IDS.ERROR_NOTIFICATION_MSG).textContent = msg;
+ if (linkName && linkOnClick) {
+ const notificationLink = $(IDS.ERROR_NOTIFICATION_LINK);
+ notificationLink.textContent = linkName;
+ notificationLink.onclick = linkOnClick;
+ notification.classList.add(CLASSES.HAS_LINK);
+ } else {
+ notification.classList.remove(CLASSES.HAS_LINK);
+ }
+ floatUpNotification(notification, $(IDS.ERROR_NOTIFICATION_CONTAINER));
+}
+
+/**
+ * Shows the Most Visited pop-up notification and triggers a delay to hide it.
+ * The message will be set to |msg|.
+ * @param {string} msg The notification message.
+ */
+function showNotification(msg) {
+ $(IDS.NOTIFICATION_MESSAGE).textContent = msg;
+ $(IDS.RESTORE_ALL_LINK).textContent = customLinksEnabled() ?
+ configData.translatedStrings.restoreDefaultLinks :
+ configData.translatedStrings.restoreThumbnailsShort;
+ floatUpNotification($(IDS.NOTIFICATION), $(IDS.NOTIFICATION_CONTAINER));
+ $(IDS.UNDO_LINK).focus();
+}
+
+/**
+ * Renders the attribution if the URL is present, otherwise hides it.
+ * @param {string|undefined} url The URL of the attribution image, if any.
+ * @param {string|undefined} themeBackgroundAlignment The alignment of the theme
+ * background image. This is used to compute the attribution's alignment.
+ */
+function updateThemeAttribution(url, themeBackgroundAlignment) {
+ if (!url) {
+ setAttributionVisibility(false);
+ return;
+ }
+
+ const attribution = $(IDS.ATTRIBUTION);
+ let attributionImage = attribution.querySelector('img');
+ if (!attributionImage) {
+ attributionImage = new Image();
+ attribution.appendChild(attributionImage);
+ }
+ attributionImage.style.content = url;
+
+ // To avoid conflicts, place the attribution on the left for themes that
+ // right align their background images.
+ attribution.classList.toggle(
+ CLASSES.LEFT_ALIGN_ATTRIBUTION, themeBackgroundAlignment == 'right');
+ setAttributionVisibility(true);
}
return {
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_single.css b/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
index 51a006495b6..995e9a8b6b6 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -45,10 +45,6 @@ a:visited {
text-decoration: none;
}
-body.hide {
- display: none;
-}
-
#most-visited {
margin-top: 10px;
text-align: -webkit-center;
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_single.html b/chromium/chrome/browser/resources/local_ntp/most_visited_single.html
index 7047423ce7e..9d8db297c9a 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.html
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.html
@@ -8,6 +8,7 @@
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="local-ntp-common.css">
<link rel="stylesheet" type="text/css" href="single.css">
+ <script src="assert.js"></script>
<script src="utils.js"></script>
<script src="single.js"></script>
</head>
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
index f26d493e0c4..c497599fdb4 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -51,7 +51,6 @@ const CLASSES = {
GRID_REORDER: 'grid-reorder',
GRID_TILE: 'grid-tile',
GRID_TILE_CONTAINER: 'grid-tile-container',
- HIDE: 'hide', // Applied when the tiles are hidden by the user.
REORDER: 'reorder', // Applied to the tile being moved while reordering.
// Applied while we are reordering. Disables hover styling.
REORDERING: 'reordering',
@@ -830,7 +829,7 @@ function handleCommand(data) {
// TODO(crbug.com/946225): If this happens before we have finished loading
// the previous tiles, we probably get into a bad state. If/when the iframe
// is removed this might no longer be a concern.
- showTiles(data);
+ showTiles();
} else if (cmd == 'updateTheme') {
updateTheme(data);
} else if (cmd === 'focusMenu') {
@@ -842,12 +841,8 @@ function handleCommand(data) {
/**
* Handler for the 'show' message from the host page.
- * @param {!Object} info Data received in the message.
*/
-function showTiles(info) {
- document.body.classList.toggle(
- CLASSES.HIDE, !chrome.embeddedSearch.newTabPage.areShortcutsVisible);
-
+function showTiles() {
utils.setPlatformClass(document.body);
countLoad();
}
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_title.html b/chromium/chrome/browser/resources/local_ntp/most_visited_title.html
index 5420eea02f9..11286d9cd6d 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_title.html
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_title.html
@@ -4,6 +4,7 @@
<meta charset="utf-8">
<link rel="stylesheet" href="common.css">
<link rel="stylesheet" href="title.css">
+ <script src="assert.js"></script>
<script src="util.js"></script>
<script src="title.js"></script>
</head>
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_util.js b/chromium/chrome/browser/resources/local_ntp/most_visited_util.js
index 0ee762a9f45..fc6a744276b 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_util.js
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_util.js
@@ -60,6 +60,12 @@ function convertArrayToRGBAColor(rgbaColor) {
* Parses query parameters from Location.
* @param {!Location} location The URL to generate the CSS url for.
* @return {Object} Dictionary containing name value pairs for URL.
+ *
+ * TODO(dbeam): we should update callers of this method to use
+ * URLSearchParams#get() instead (which I have a higher confidence handles
+ * escaping and edge cases correctly). Note: that calling URLSearchParams#get()
+ * also has the behavior of only returning the first &param= in the URL (i.e.
+ * ?param=1&param=2 + .get('param') would return '1').
*/
function parseQueryParams(location) {
const params = Object.create(null);
@@ -169,7 +175,7 @@ function getTextColor(params, isTitle) {
// For backward compatibility with server-side NTP, look at themes directly
// and use param.c for non-title or as fallback.
const apiHandle = chrome.embeddedSearch.newTabPage;
- const themeInfo = apiHandle.themeBackgroundInfo;
+ const themeInfo = assert(apiHandle.themeBackgroundInfo);
let c = '#777';
if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
// Read from theme directly
diff --git a/chromium/chrome/browser/resources/local_state/BUILD.gn b/chromium/chrome/browser/resources/local_state/BUILD.gn
index 3a34954d26d..d621c9424d7 100644
--- a/chromium/chrome/browser/resources/local_state/BUILD.gn
+++ b/chromium/chrome/browser/resources/local_state/BUILD.gn
@@ -12,7 +12,7 @@ js_type_check("closure_compile") {
js_library("local_state") {
deps = [
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:util.m",
]
}
diff --git a/chromium/chrome/browser/resources/local_state/local_state.html b/chromium/chrome/browser/resources/local_state/local_state.html
index 71dc1d4957d..72795b90cb4 100644
--- a/chromium/chrome/browser/resources/local_state/local_state.html
+++ b/chromium/chrome/browser/resources/local_state/local_state.html
@@ -4,10 +4,7 @@
<meta charset="utf-8">
<title>Local State Debug Page</title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
- <script src="chrome://resources/js/promise_resolver.js"></script>
- <script src="chrome://resources/js/cr.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="local_state.js"></script>
+ <script type="module" src="local_state.js"></script>
</head>
<body>
<pre id="content">
diff --git a/chromium/chrome/browser/resources/local_state/local_state.js b/chromium/chrome/browser/resources/local_state/local_state.js
index 5dc929be49b..d5191e236ae 100644
--- a/chromium/chrome/browser/resources/local_state/local_state.js
+++ b/chromium/chrome/browser/resources/local_state/local_state.js
@@ -6,10 +6,12 @@
* Javascript for local_state.html, served from chrome://local-state/
* This is used to debug the contents of the Local State file.
*/
+import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {$} from 'chrome://resources/js/util.m.js';
// When the page loads, request the JSON local state data from C++.
document.addEventListener('DOMContentLoaded', function() {
- cr.sendWithPromise('requestJson').then(localState => {
+ sendWithPromise('requestJson').then(localState => {
$('content').textContent = localState;
});
});
diff --git a/chromium/chrome/browser/resources/management/management_browser_proxy.js b/chromium/chrome/browser/resources/management/management_browser_proxy.js
index 0633bdcb930..a86bbaa7b15 100644
--- a/chromium/chrome/browser/resources/management/management_browser_proxy.js
+++ b/chromium/chrome/browser/resources/management/management_browser_proxy.js
@@ -36,10 +36,27 @@ cr.define('management', function() {
* managed: boolean,
* overview: string,
* customerLogo: string,
+ * threatProtectionDescription: string
* }}
*/
let ManagedDataResponse;
+ /**
+ * @typedef {{
+ * title: string,
+ * permission: string
+ * }}
+ */
+ let ThreatProtectionPermission;
+
+ /**
+ * @typedef {{
+ * info: !Array<!ThreatProtectionPermission>,
+ * description: string
+ * }}
+ */
+ let ThreatProtectionInfo;
+
// <if expr="chromeos">
/**
* @enum {string} Look at ToJSDeviceReportingType usage in
@@ -87,6 +104,9 @@ cr.define('management', function() {
/** @return {!Promise<!management.ManagedDataResponse>} */
getContextualManagedData() {}
+ /** @return {!Promise<!management.ThreatProtectionInfo>} */
+ getThreatProtectionInfo() {}
+
/**
* @return {!Promise<!Array<!management.BrowserReportingResponse>>} The list
* of browser reporting info messages.
@@ -119,6 +139,11 @@ cr.define('management', function() {
}
/** @override */
+ getThreatProtectionInfo() {
+ return cr.sendWithPromise('getThreatProtectionInfo');
+ }
+
+ /** @override */
initBrowserReportingInfo() {
return cr.sendWithPromise('initBrowserReportingInfo');
}
@@ -137,5 +162,6 @@ cr.define('management', function() {
ManagementBrowserProxyImpl: ManagementBrowserProxyImpl,
ManagementBrowserProxy: ManagementBrowserProxy,
ReportingType: ReportingType,
+ ThreatProtectionInfo: ThreatProtectionInfo,
};
});
diff --git a/chromium/chrome/browser/resources/management/management_ui.html b/chromium/chrome/browser/resources/management/management_ui.html
index 725e38c4263..f52326d1ad8 100644
--- a/chromium/chrome/browser/resources/management/management_ui.html
+++ b/chromium/chrome/browser/resources/management/management_ui.html
@@ -52,9 +52,10 @@
.page-subtitle {
align-items: center;
+ box-sizing: border-box;
flex-direction: row;
justify-content: start;
- min-height: 40px;
+ min-height: 73px;
padding-bottom: 24px;
padding-top: 6px;
}
@@ -125,11 +126,12 @@
}
.content-indented {
- margin-inline-start: 24px;
+ padding-inline-start: 24px;
}
table {
border-spacing: 0 16px;
+ box-sizing: border-box;
width: 100%;
}
@@ -143,7 +145,8 @@
display: flex;
}
- .extension-name {
+ .extension-name,
+ .protection-name {
width: 40%;
}
@@ -154,10 +157,16 @@
white-space: nowrap;
}
- .extension-permissions {
+ .extension-permissions,
+ .protection-permissions {
width: 60%;
}
+ .protection-name,
+ .protection-permissions {
+ vertical-align: top;
+ }
+
.extension-name img {
height: 20px;
margin-inline-end: 12px;
@@ -199,6 +208,33 @@
</div>
</if>
</section>
+ <template is="dom-if"
+ if="[[showThreatProtectionInfo_(threatProtectionInfo_)]]">
+ <section>
+ <h2 class="cr-title-text">$i18n{threatProtectionTitle}</h2>
+ <div class="subtitle">
+ [[threatProtectionInfo_.description]]
+ </div>
+ <table class="content-indented">
+ <tr>
+ <th class="protection-name">$i18n{extensionName}</th>
+ <th class="protection-permissions">
+ $i18n{extensionPermissions}
+ </th>
+ </tr>
+ <template is="dom-repeat"
+ items="[[threatProtectionInfo_.info]]">
+ <tr>
+ <td class="protection-name">[[i18n(item.title)]]</td>
+ <td class="protection-permissions">
+ [[i18n(item.permission)]]
+ </td>
+ </tr>
+ </template>
+ </table>
+ </section>
+ </template>
+
<if expr="chromeos">
<div hidden="[[!localTrustRoots_]]">
<section>
@@ -259,10 +295,10 @@
</div>
<table class="content-indented">
<tr>
- <th class="extension-name">$i18n{extensionName}</td>
+ <th class="extension-name">$i18n{extensionName}</th>
<th class="extension-permissions">
$i18n{extensionPermissions}
- </td>
+ </th>
</tr>
<template is="dom-repeat" items="[[extensions_]]">
<tr>
diff --git a/chromium/chrome/browser/resources/management/management_ui.js b/chromium/chrome/browser/resources/management/management_ui.js
index a4984aa83d7..a04d5ed4935 100644
--- a/chromium/chrome/browser/resources/management/management_ui.js
+++ b/chromium/chrome/browser/resources/management/management_ui.js
@@ -66,6 +66,9 @@ cr.define('management', function() {
/** @private */
extensionReportingSubtitle_: String,
+
+ /** @private {!management.ThreatProtectionInfo} */
+ threatProtectionInfo_: Object,
},
/** @private {?management.ManagementBrowserProxy} */
@@ -77,6 +80,7 @@ cr.define('management', function() {
this.browserProxy_ = management.ManagementBrowserProxyImpl.getInstance();
this.updateManagedFields_();
this.initBrowserReportingInfo_();
+ this.getThreatProtectionInfo_();
this.addWebUIListener(
'browser-reporting-info-updated',
@@ -86,6 +90,10 @@ cr.define('management', function() {
this.updateManagedFields_();
});
+ this.addWebUIListener(
+ 'threat-protection-info-updated',
+ info => this.threatProtectionInfo_ = info);
+
this.getExtensions_();
// <if expr="chromeos">
this.getDeviceReportingInfo_();
@@ -134,6 +142,22 @@ cr.define('management', function() {
});
},
+ /** @private */
+ getThreatProtectionInfo_() {
+ this.browserProxy_.getThreatProtectionInfo().then(info => {
+ this.threatProtectionInfo_ = info;
+ });
+ },
+
+ /**
+ * @return {boolean} True if there is threat protection info to show.
+ * @private
+ */
+ showThreatProtectionInfo_() {
+ return !!this.threatProtectionInfo_ &&
+ this.threatProtectionInfo_.info.length > 0;
+ },
+
// <if expr="chromeos">
/** @private */
getLocalTrustRootsInfo_() {
diff --git a/chromium/chrome/browser/resources/media/media_engagement.html b/chromium/chrome/browser/resources/media/media_engagement.html
index 8922e663882..b1a0fdf1a52 100644
--- a/chromium/chrome/browser/resources/media/media_engagement.html
+++ b/chromium/chrome/browser/resources/media/media_engagement.html
@@ -140,27 +140,12 @@
<th sort-key="mediaPlaybacks" sort-reverse>
Sessions with playback
</th>
- <th sort-key="audioContextPlaybacks" sort-reverse>
- Sessions with playback<br>(audio context only)
- </th>
- <th sort-key="mediaElementPlaybacks" sort-reverse>
- Sessions with playback<br>(media element only)
- </th>
- <th sort-key="audiblePlaybacks" sort-reverse>
- Audible Playbacks*
- </th>
- <th sort-key="significantPlaybacks" sort-reverse>
- Significant Playbacks*
- </th>
<th sort-key="lastMediaPlaybackTime" sort-reverse>
Last Playback
</th>
<th sort-key="isHigh" sort-reverse>
Is High
</th>
- <th sort-key="highScoreChanges" sort-reverse>
- Is High Changes
- </th>
<th sort-key="totalScore" class="sort-column" sort-reverse>
Score
</th>
@@ -170,22 +155,13 @@
</tbody>
</table>
- <p>
- * These columns are experimental and do not currently affect the MEI score.
- </p>
-
<template id="datarow">
<tr>
<td class="origin-cell"></td>
<td class="visits-count-cell"></td>
<td class="media-playbacks-count-cell"></td>
- <td class="audio-context-playbacks-count-cell"></td>
- <td class="media-element-playbacks-count-cell"></td>
- <td class="audible-playbacks-count-cell"></td>
- <td class="significant-playbacks-count-cell"></td>
<td class="last-playback-time-cell"></td>
<td class="is-high-cell"></td>
- <td class="is-high-changes-cell"></td>
<td class="total-score-cell"></td>
<td class="engagement-bar-cell">
<div class="engagement-bar"></div>
diff --git a/chromium/chrome/browser/resources/media/media_engagement.js b/chromium/chrome/browser/resources/media/media_engagement.js
index 5491928b222..d56ef21e6ff 100644
--- a/chromium/chrome/browser/resources/media/media_engagement.js
+++ b/chromium/chrome/browser/resources/media/media_engagement.js
@@ -13,7 +13,7 @@ function whenPageIsPopulatedForTest() {
(function() {
-let uiHandler = null;
+let detailsProvider = null;
let info = null;
let engagementTableBody = null;
let sortReverse = true;
@@ -39,17 +39,12 @@ function createRow(rowInfo) {
td[1].textContent = rowInfo.visits;
td[2].textContent = rowInfo.mediaPlaybacks;
- td[3].textContent = rowInfo.audioContextPlaybacks;
- td[4].textContent = rowInfo.mediaElementPlaybacks;
- td[5].textContent = rowInfo.audiblePlaybacks;
- td[6].textContent = rowInfo.significantPlaybacks;
- td[7].textContent = rowInfo.lastMediaPlaybackTime ?
+ td[3].textContent = rowInfo.lastMediaPlaybackTime ?
new Date(rowInfo.lastMediaPlaybackTime).toISOString() :
'';
- td[8].textContent = rowInfo.isHigh ? 'Yes' : 'No';
- td[9].textContent = rowInfo.highScoreChanges;
- td[10].textContent = rowInfo.totalScore ? rowInfo.totalScore.toFixed(2) : '0';
- td[11].getElementsByClassName('engagement-bar')[0].style.width =
+ td[4].textContent = rowInfo.isHigh ? 'Yes' : 'No';
+ td[5].textContent = rowInfo.totalScore ? rowInfo.totalScore.toFixed(2) : '0';
+ td[6].getElementsByClassName('engagement-bar')[0].style.width =
(rowInfo.totalScore * 50) + 'px';
return document.importNode(template.content, true);
}
@@ -180,20 +175,20 @@ function renderTable() {
*/
function updateEngagementTable() {
// Populate engagement table.
- uiHandler.getMediaEngagementScoreDetails().then(response => {
+ detailsProvider.getMediaEngagementScoreDetails().then(response => {
info = response.info;
renderTable();
pageIsPopulatedResolver.resolve();
});
// Populate config settings.
- uiHandler.getMediaEngagementConfig().then(response => {
+ detailsProvider.getMediaEngagementConfig().then(response => {
renderConfigTable(response.config);
});
}
document.addEventListener('DOMContentLoaded', function() {
- uiHandler = media.mojom.MediaEngagementScoreDetailsProvider.getProxy();
+ detailsProvider = media.mojom.MediaEngagementScoreDetailsProvider.getRemote();
updateEngagementTable();
engagementTableBody = $('engagement-table-body');
diff --git a/chromium/chrome/browser/resources/media_router/extension/BUILD.gn b/chromium/chrome/browser/resources/media_router/extension/BUILD.gn
index 8728b3b4f02..a1b45248410 100644
--- a/chromium/chrome/browser/resources/media_router/extension/BUILD.gn
+++ b/chromium/chrome/browser/resources/media_router/extension/BUILD.gn
@@ -1,11 +1,5 @@
import("src/files.gni")
-group("all") {
- deps = [
- ":media_router",
- ]
-}
-
declare_args() {
# Determines whether JSCompiler should be used to typecheck
# JavaScript code for the Media Router extension.
@@ -72,7 +66,7 @@ action("media_router") {
outputs = [
"$target_gen_dir/manifest.json",
]
- deps = [
+ data_deps = [
":copy_prelude",
":media_router_modules",
]
diff --git a/chromium/chrome/browser/resources/ntp4/dot_list.js b/chromium/chrome/browser/resources/ntp4/dot_list.js
index 9e5bdfaca44..d37ff53dfbc 100644
--- a/chromium/chrome/browser/resources/ntp4/dot_list.js
+++ b/chromium/chrome/browser/resources/ntp4/dot_list.js
@@ -11,7 +11,7 @@ cr.define('ntp', function() {
/**
* Live list of the navigation dots.
- * @type {!NodeList|undefined}
+ * @type {!HTMLCollection<!Element>}
*/
let navDots;
diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.html b/chromium/chrome/browser/resources/ntp4/new_tab.html
index 2cc968e011d..de19cad2443 100644
--- a/chromium/chrome/browser/resources/ntp4/new_tab.html
+++ b/chromium/chrome/browser/resources/ntp4/new_tab.html
@@ -34,7 +34,6 @@ document.write('<link id="themecss" rel="stylesheet" ' +
<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/icon.js"></script>
<script src="../../../../ui/webui/resources/js/cr.js"></script>
<script src="../../../../ui/webui/resources/js/cr/event_target.js"></script>
@@ -49,6 +48,7 @@ document.write('<link id="themecss" rel="stylesheet" ' +
<script src="../../../../ui/webui/resources/js/cr/ui/position_util.js"></script>
<script src="../../../../ui/webui/resources/js/cr/ui/menu_button.js"></script>
<script src="../../../../ui/webui/resources/js/cr/ui/touch_handler.js"></script>
+<script src="../../../../ui/webui/resources/js/icon.js"></script>
<script src="tile_page.js"></script>
<script src="apps_page.js"></script>
diff --git a/chromium/chrome/browser/resources/ntp4/page_list_view.js b/chromium/chrome/browser/resources/ntp4/page_list_view.js
index 3a878c35ac5..b9e093a44e1 100644
--- a/chromium/chrome/browser/resources/ntp4/page_list_view.js
+++ b/chromium/chrome/browser/resources/ntp4/page_list_view.js
@@ -78,13 +78,13 @@ cr.define('ntp', function() {
/**
* A list of all 'tile-page' elements.
- * @type {!NodeList|undefined}
+ * @type {!HTMLCollection<!ntp.TilePage>|undefined}
*/
tilePages: undefined,
/**
* A list of all 'apps-page' elements.
- * @type {!NodeList|undefined}
+ * @type {!HTMLCollection<!ntp.AppsPage>|undefined}
*/
appsPages: undefined,
@@ -175,8 +175,10 @@ cr.define('ntp', function() {
document.addEventListener('keydown', this.onDocKeyDown_.bind(this));
- this.tilePages = this.pageList.getElementsByClassName('tile-page');
- this.appsPages = this.pageList.getElementsByClassName('apps-page');
+ this.tilePages = /** @type {!HTMLCollection<!ntp.TilePage>} */ (
+ this.pageList.getElementsByClassName('tile-page'));
+ this.appsPages = /** @type {!HTMLCollection<!ntp.AppsPage>} */ (
+ this.pageList.getElementsByClassName('apps-page'));
// Initialize the cardSlider without any cards at the moment.
this.sliderFrame = cardSliderFrame;
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox.html b/chromium/chrome/browser/resources/omnibox/omnibox.html
index 1f9f1f8e96b..402bef06eb3 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox.html
+++ b/chromium/chrome/browser/resources/omnibox/omnibox.html
@@ -6,6 +6,7 @@
<title>Omnibox Debug Page</title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="omnibox.css">
+ <script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
@@ -108,6 +109,7 @@
</option>
<option value="7">new tab page omnibox</option>
<option value="8">new tab page fakebox</option>
+ <option value="15">new tab page realbox</option>
<option value="1">(OBSOLETE) new tab page</option>
</select>
</div>
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox.js b/chromium/chrome/browser/resources/omnibox/omnibox.js
index 5c2c818e7ec..c5d0e722454 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox.js
+++ b/chromium/chrome/browser/resources/omnibox/omnibox.js
@@ -71,7 +71,7 @@ class BrowserProxy {
this.handler_.setClientPage(
this.callbackRouter_.$.bindNewPipeAndPassRemote());
- /** @private {Request} */
+ /** @private {?Request} */
this.lastRequest;
}
@@ -81,8 +81,13 @@ class BrowserProxy {
* @param {boolean} isPageController
*/
handleNewAutocompleteResponse(response, isPageController) {
+ // Note: Using inputText is a sufficient fix for the way this is used today,
+ // but in principle it would be better to associate requests with responses
+ // using a unique session identifier, for example by rolling an integer each
+ // time a request is made. Doing so would require extra bookkeeping on the
+ // host side, so for now we keep it simple.
const isForLastPageRequest = isPageController && this.lastRequest &&
- this.lastRequest.inputText === response.host;
+ this.lastRequest.inputText === response.inputText;
// When unfocusing the browser omnibox, the autocomplete controller
// sends a response with no combined results. This response is ignored
@@ -95,6 +100,9 @@ class BrowserProxy {
omniboxOutput.addAutocompleteResponse(response);
}
+ // TODO(orinj|manukh): If |response.done| but not |isForLastPageRequest|
+ // then callback is being dropped. We should guarantee that callback is
+ // always called because some callers await promises.
if (isForLastPageRequest && response.done) {
this.lastRequest.callback(response);
this.lastRequest = null;
@@ -234,18 +242,29 @@ class ExportDelegate {
};
batchExports.push(exportData);
}
+ const variationInfo =
+ await cr.sendWithPromise('requestVariationInfo', true);
+ const pathInfo = await cr.sendWithPromise('requestPathInfo');
+ const loadTimeDataKeys = ['cl', 'command_line', 'executable_path',
+ 'language', 'official', 'os_type', 'profile_path', 'useragent',
+ 'version', 'version_bitsize', 'version_modifier'];
+ const versionDetails = Object.fromEntries(
+ loadTimeDataKeys.map(key => [key, window.loadTimeData.getValue(key)]));
+
const now = new Date();
const fileName = `omnibox_batch_${ExportDelegate.getTimeStamp(now)}.json`;
// If this data format changes, please roll schemaVersion.
const batchData = {
schemaKind: 'Omnibox Batch Export',
- schemaVersion: 2,
+ schemaVersion: 3,
dateCreated: now.toISOString(),
author: '',
description: '',
authorTool: 'chrome://omnibox',
batchName,
- versionDetails: window.loadTimeData.data_,
+ versionDetails,
+ variationInfo,
+ pathInfo,
appVersion: navigator.appVersion,
batchExports
};
@@ -322,7 +341,7 @@ class ExportDelegate {
a.click();
}
- /**
+ /**
* @param {Date=} date
* @return {string} A sortable timestamp string for use in filenames.
*/
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox_output.js b/chromium/chrome/browser/resources/omnibox/omnibox_output.js
index fb578cadce8..72184d02c97 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox_output.js
+++ b/chromium/chrome/browser/resources/omnibox/omnibox_output.js
@@ -727,7 +727,7 @@ cr.define('omnibox_output', function() {
*/
static renderClassifiedText_(container, string, classes) {
clearChildren(container);
- OutputAnswerProperty.classify(string + '\n', classes)
+ OutputAnswerProperty.classify(string, classes)
.map(
({string, style}) => OutputJsonProperty.renderJsonWord(
string, OutputAnswerProperty.styleToClasses_(style)))
@@ -1054,6 +1054,10 @@ cr.define('omnibox_output', function() {
],
OutputAnswerProperty),
new Column(
+ ['S'], '', 'swapContentsAndDescription', false,
+ 'Swap Contents and Description', ['swapContentsAndDescription'],
+ OutputBooleanProperty),
+ new Column(
['D'], '', '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 ' +
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 beff890c350..45c82783cde 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css
+++ b/chromium/chrome/browser/resources/omnibox/omnibox_output_column_widths.css
@@ -36,6 +36,7 @@
width: 240%;
}
+.header-swap-contents-and-description,
.header-allowed-to-be-default-match,
.header-starred,
.header-has-tab-match,
diff --git a/chromium/chrome/browser/resources/omnibox/output_results_group.css b/chromium/chrome/browser/resources/omnibox/output_results_group.css
index 56f5d510296..c46e20e82aa 100644
--- a/chromium/chrome/browser/resources/omnibox/output_results_group.css
+++ b/chromium/chrome/browser/resources/omnibox/output_results_group.css
@@ -54,6 +54,7 @@ table {
}
.body td {
+ white-space: pre-wrap;
word-break: break-all;
}
@@ -62,7 +63,7 @@ table {
}
.body td.elided:not(:hover) {
- white-space: nowrap;
+ white-space: pre;
}
.body td:not(:hover) * {
diff --git a/chromium/chrome/browser/resources/pdf/BUILD.gn b/chromium/chrome/browser/resources/pdf/BUILD.gn
index 1483ff4a9a0..89a0223ca86 100644
--- a/chromium/chrome/browser/resources/pdf/BUILD.gn
+++ b/chromium/chrome/browser/resources/pdf/BUILD.gn
@@ -14,6 +14,9 @@ group("closure_compile") {
"elements/viewer-page-indicator:closure_compile",
"elements/viewer-page-selector:closure_compile",
"elements/viewer-password-screen:closure_compile",
+ "elements/viewer-pdf-toolbar:closure_compile",
+ "elements/viewer-toolbar-dropdown:closure_compile",
+ "elements/viewer-zoom-toolbar:closure_compile",
]
if (is_chromeos) {
deps += [
@@ -54,17 +57,12 @@ js_library("pdf_scripting_api") {
js_library("viewport_scroller") {
}
-js_library("viewport_interface") {
- deps = [
- ":pdf_fitting_type",
- ]
-}
-
js_library("viewport") {
deps = [
":gesture_detector",
- ":viewport_interface",
+ ":pdf_fitting_type",
":zoom_manager",
+ "//ui/webui/resources/js:event_tracker",
"//ui/webui/resources/js:util",
]
externs_list = [ "$externs_path/pending.js" ]
@@ -73,7 +71,7 @@ js_library("viewport") {
js_library("zoom_manager") {
deps = [
":browser_api",
- ":viewport_interface",
+ "//ui/webui/resources/js/cr:event_target",
]
}
@@ -81,16 +79,23 @@ js_library("metrics") {
externs_list = [ "$externs_path/metrics_private.js" ]
}
+js_library("navigator") {
+ deps = [
+ ":open_pdf_params_parser",
+ ":viewport",
+ ]
+}
+
js_type_check("pdf_resources") {
deps = [
":browser_api",
":gesture_detector",
":metrics",
+ ":navigator",
":open_pdf_params_parser",
":pdf_fitting_type",
":pdf_scripting_api",
":viewport",
- ":viewport_interface",
":viewport_scroller",
":zoom_manager",
]
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
index ae14eeb289f..004aa1b1677 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
@@ -49,21 +49,21 @@
transform: rotate(180deg);
}
- :host([children-shown]) #expand {
+ :host([children-shown_]) #expand {
transform: rotate(90deg);
}
</style>
- <div id="item" on-click="onClick">
+ <div id="item" on-click="onClick_">
<paper-ripple></paper-ripple>
<cr-icon-button id="expand" iron-icon="cr:chevron-right"
- on-click="toggleChildren"></cr-icon-button>
+ on-click="toggleChildren_"></cr-icon-button>
<span id="title" tabindex="0">{{bookmark.title}}</span>
</div>
<!-- dom-if will stamp the complex bookmark tree lazily as individual nodes
are opened. -->
- <template is="dom-if" if="[[childrenShown]]" id="sub-bookmarks">
+ <template is="dom-if" if="[[childrenShown_]]">
<template is="dom-repeat" items="[[bookmark.children]]">
- <viewer-bookmark bookmark="{{item}}" depth="{{childDepth}}">
+ <viewer-bookmark bookmark="{{item}}" depth="[[childDepth_]]">
</viewer-bookmark>
</template>
</template>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
index 160191b6ecb..f1cce48abaa 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
@@ -15,9 +15,9 @@
* structure.
* @typedef {{
* title: string,
- * page: number,
- * y: number,
- * uri: string,
+ * page: (number | undefined),
+ * y: (number | undefined),
+ * uri: (string | undefined),
* children: !Array<!Bookmark>
* }}
*/
@@ -32,13 +32,25 @@ Polymer({
properties: {
/** @type {Bookmark} */
- bookmark: {type: Object, observer: 'bookmarkChanged_'},
-
- depth: {type: Number, observer: 'depthChanged'},
-
- childDepth: Number,
-
- childrenShown: {type: Boolean, reflectToAttribute: true, value: false},
+ bookmark: {
+ type: Object,
+ observer: 'bookmarkChanged_',
+ },
+
+ depth: {
+ type: Number,
+ observer: 'depthChanged_'
+ },
+
+ /** @private */
+ childDepth_: Number,
+
+ /** @private */
+ childrenShown_: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
/** @type {?HTMLElement} The target for the key bindings below. */
keyEventTarget: Object,
@@ -53,18 +65,21 @@ Polymer({
this.keyEventTarget = this.$.item;
},
+ /** @private */
bookmarkChanged_: function() {
this.$.expand.style.visibility =
this.bookmark.children.length > 0 ? 'visible' : 'hidden';
},
- depthChanged: function() {
- this.childDepth = this.depth + 1;
+ /** @private */
+ depthChanged_: function() {
+ this.childDepth_ = this.depth + 1;
this.$.item.style.paddingInlineStart =
(this.depth * BOOKMARK_INDENT) + 'px';
},
- onClick: function() {
+ /** @private */
+ onClick_: function() {
if (this.bookmark.hasOwnProperty('page')) {
if (this.bookmark.hasOwnProperty('y')) {
this.fire('change-page-and-xy', {
@@ -82,25 +97,37 @@ Polymer({
}
},
+ /**
+ * @param {!KeyboardEvent} e
+ * @private
+ */
onEnter_: function(e) {
// Don't allow events which have propagated up from the expand button to
// trigger a click.
if (e.detail.keyboardEvent.target != this.$.expand) {
- this.onClick();
+ this.onClick_();
}
},
+ /**
+ * @param {!KeyboardEvent} e
+ * @private
+ */
onSpace_: function(e) {
// cr-icon-button stops propagation of space events, so there's no need
// to check the event source here.
- this.onClick();
+ this.onClick_();
// Prevent default space scroll behavior.
e.detail.keyboardEvent.preventDefault();
},
- toggleChildren: function(e) {
- this.childrenShown = !this.childrenShown;
- e.stopPropagation(); // Prevent the above onClick handler from firing.
+ /**
+ * @param {!Event} e
+ * @private
+ */
+ toggleChildren_: function(e) {
+ this.childrenShown_ = !this.childrenShown_;
+ e.stopPropagation(); // Prevent the above onClick_ handler from firing.
}
});
})();
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html
deleted file mode 100644
index 2277ec4d941..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="../viewer-bookmark/viewer-bookmark.html">
-
-<dom-module id="viewer-bookmarks-content">
- <template>
- <template is="dom-repeat" items="[[bookmarks]]">
- <viewer-bookmark bookmark="{{item}}" depth="0"></viewer-bookmark>
- </template>
- </template>
- <script src="viewer-bookmarks-content.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js
deleted file mode 100644
index 32f3fd320d5..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmarks-content/viewer-bookmarks-content.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2015 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.
-
-Polymer({is: 'viewer-bookmarks-content'});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js
index 6bb2e4c68ed..285edf8a35d 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js
@@ -47,7 +47,7 @@ Polymer({
/** @private {boolean} */
penMode_: false,
- /** @type {Viewport} */
+ /** @type {?Viewport} */
viewport: null,
/** @type {?AnnotationTool} */
@@ -247,7 +247,7 @@ Polymer({
const viewport = this.viewport;
const pos = viewport.position;
const size = viewport.size;
- const zoom = viewport.zoom;
+ const zoom = viewport.getZoom();
const documentWidth = viewport.getDocumentDimensions().width * zoom;
// Adjust for page shadows.
const y = pos.y - Viewport.PAGE_SHADOW.top * zoom;
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn
new file mode 100644
index 00000000000..fdc650f55b9
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn
@@ -0,0 +1,20 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":viewer-pdf-toolbar",
+ ]
+}
+
+js_library("viewer-pdf-toolbar") {
+ deps = [
+ "../viewer-bookmark:viewer-bookmark",
+ "../viewer-page-selector:viewer-page-selector",
+ "../viewer-toolbar-dropdown:viewer-toolbar-dropdown",
+ ]
+ externs_list = [ "$externs_path/pending.js" ]
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
index f6454c97a5c..e183debc86d 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
@@ -5,7 +5,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="../icons.html">
-<link rel="import" href="../viewer-bookmarks-content/viewer-bookmarks-content.html">
+<link rel="import" href="../viewer-bookmark/viewer-bookmark.html">
<link rel="import" href="../viewer-page-selector/viewer-page-selector.html">
<if expr="chromeos">
<link rel="import" href="../viewer-pen-options/viewer-pen-options.html">
@@ -214,8 +214,9 @@
open-icon="pdf:bookmark"
closed-icon="pdf:bookmark-border"
header="{{strings.bookmarks}}">
- <viewer-bookmarks-content bookmarks="{{bookmarks}}">
- </viewer-bookmarks-content>
+ <template is="dom-repeat" items="[[bookmarks]]">
+ <viewer-bookmark bookmark="[[item]]" depth="0"></viewer-bookmark>
+ </template>
</viewer-toolbar-dropdown>
</div>
</div>
@@ -228,7 +229,7 @@
<div id="annotations-bar" hidden>
<viewer-toolbar-dropdown id="pen"
- selected$="[[equal_('pen', annotationTool.tool)]]"
+ selected$="[[isAnnotationTool_('pen', annotationTool.tool)]]"
open-after-select
on-click="annotationToolClicked_"
open-icon="pdf:marker"
@@ -247,7 +248,7 @@
</viewer-toolbar-dropdown>
<viewer-toolbar-dropdown id="highlighter"
- selected$="[[equal_('highlighter', annotationTool.tool)]]"
+ selected$="[[isAnnotationTool_('highlighter', annotationTool.tool)]]"
open-after-select
on-click="annotationToolClicked_"
open-icon="pdf:highlighter"
@@ -266,7 +267,7 @@
</viewer-toolbar-dropdown>
<cr-icon-button id="eraser"
- selected$="[[equal_('eraser', annotationTool.tool)]]"
+ selected$="[[isAnnotationTool_('eraser', annotationTool.tool)]]"
on-click="annotationToolClicked_" iron-icon="pdf:eraser"
aria-label$="{{strings.annotationEraser}}"
title$="{{strings.annotationEraser}}"></cr-icon-button>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
index 006aa5ca5b8..afb87dfe6b7 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js
@@ -7,38 +7,16 @@ Polymer({
properties: {
/**
- * The current loading progress of the PDF document (0 - 100).
- */
- loadProgress: {type: Number, observer: 'loadProgressChanged_'},
-
- /**
- * The title of the PDF document.
- */
- docTitle: String,
-
- /**
- * The number of the page being viewed (1-based).
- */
- pageNo: Number,
-
- /**
- * Tree of PDF bookmarks (or null if the document has no bookmarks).
- */
- bookmarks: {type: Object, value: null},
-
- /**
- * The number of pages in the PDF document.
- */
- docLength: Number,
-
- /**
- * Whether the toolbar is opened and visible.
+ * Whether annotation mode can be entered. This would be false if for
+ * example the PDF is encrypted or password protected. Note, this is
+ * true regardless of whether the feature flag is enabled.
*/
- opened: {type: Boolean, value: true},
+ annotationAvailable: {
+ type: Boolean,
+ value: true,
+ },
- /**
- * Whether the viewer is currently in annotation mode.
- */
+ /** Whether the viewer is currently in annotation mode. */
annotationMode: {
type: Boolean,
notify: true,
@@ -46,6 +24,7 @@ Polymer({
reflectToAttribute: true,
},
+ /** @type {?Object} */
annotationTool: {
type: Object,
value: null,
@@ -53,13 +32,17 @@ Polymer({
},
/**
- * Whether annotation mode can be entered. This would be false if for
- * example the PDF is encrypted or password protected. Note, this is
- * true regardless of whether the feature flag is enabled.
+ * Tree of PDF bookmarks (empty if the document has no bookmarks).
+ * @type {!Array<!Bookmark>}
*/
- annotationAvailable: {
+ bookmarks: {
+ type: Array,
+ value: () => [],
+ },
+
+ canRedoAnnotation: {
type: Boolean,
- value: true,
+ value: false,
},
canUndoAnnotation: {
@@ -67,22 +50,34 @@ Polymer({
value: false,
},
- canRedoAnnotation: {
+ /** The number of pages in the PDF document. */
+ docLength: Number,
+
+ /** The title of the PDF document. */
+ docTitle: String,
+
+ /** The current loading progress of the PDF document (0 - 100). */
+ loadProgress: {
+ type: Number,
+ observer: 'loadProgressChanged_',
+ },
+
+ /** Whether the toolbar is opened and visible. */
+ opened: {
type: Boolean,
- value: false,
+ value: true,
},
- /**
- * Whether the PDF Annotations feature is enabled.
- */
+ /** The number of the page being viewed (1-based). */
+ pageNo: Number,
+
+ /** Whether the PDF Annotations feature is enabled. */
pdfAnnotationsEnabled: {
type: Boolean,
value: false,
},
- /**
- * Whether the Printing feature is enabled.
- */
+ /** Whether the Printing feature is enabled. */
printingEnabled: {
type: Boolean,
value: false,
@@ -91,6 +86,9 @@ Polymer({
strings: Object,
},
+ /** @type {?Object} */
+ animation_: null,
+
/**
* @param {number} newProgress
* @param {number} oldProgress
@@ -130,22 +128,16 @@ Polymer({
if (this.opened) {
this.animation_ = this.animate(
- {
- transform: ['translateY(-100%)', 'translateY(0%)'],
- },
- {
- easing: 'cubic-bezier(0, 0, 0.2, 1)',
+ [{transform: 'translateY(-100%)'}, {transform: 'translateY(0%)'}], {
duration: 250,
+ easing: 'cubic-bezier(0, 0, 0.2, 1)',
fill: 'forwards',
});
} else {
this.animation_ = this.animate(
- {
- transform: ['translateY(0%)', 'translateY(-100%)'],
- },
- {
- easing: 'cubic-bezier(0.4, 0, 1, 1)',
+ [{transform: 'translateY(0%)'}, {transform: 'translateY(-100%)'}], {
duration: 250,
+ easing: 'cubic-bezier(0.4, 0, 1, 1)',
fill: 'forwards',
});
}
@@ -155,11 +147,13 @@ Polymer({
this.$.pageselector.select();
},
+ /** @return {boolean} Whether the toolbar should be kept open. */
shouldKeepOpen: function() {
return this.$.bookmarks.dropdownOpen || this.loadProgress < 100 ||
this.$.pageselector.isActive() || this.annotationMode;
},
+ /** @return {boolean} Whether a dropdown was open and was hidden. */
hideDropdowns: function() {
let result = false;
if (this.$.bookmarks.dropdownOpen) {
@@ -177,6 +171,7 @@ Polymer({
return result;
},
+ /** @param {number} lowerBound */
setDropdownLowerBound: function(lowerBound) {
this.$.bookmarks.lowerBound = lowerBound;
},
@@ -214,12 +209,18 @@ Polymer({
}));
},
- /** @param {Event} e */
+ /**
+ * @param {!Event} e
+ * @private
+ */
annotationToolClicked_: function(e) {
- this.updateAnnotationTool_(e.currentTarget);
+ this.updateAnnotationTool_(/** @type {!HTMLElement} */ (e.currentTarget));
},
- /** @param {Event} e */
+ /**
+ * @param {!Event} e
+ * @private
+ */
annotationToolOptionChanged_: function(e) {
const element = e.currentTarget.parentElement;
if (!this.annotationTool || element.id != this.annotationTool.tool) {
@@ -228,15 +229,19 @@ Polymer({
this.updateAnnotationTool_(e.currentTarget.parentElement);
},
- /** @param {Element} element */
+ /**
+ * @param {!HTMLElement} element
+ * @private
+ */
updateAnnotationTool_: function(element) {
const tool = element.id;
const options = element.querySelector('viewer-pen-options') || {
selectedSize: 1,
selectedColor: null,
};
- element.attributeStyleMap.set('--pen-tip-fill', options.selectedColor);
- element.attributeStyleMap.set(
+ const attributeStyleMap = element.attributeStyleMap;
+ attributeStyleMap.set('--pen-tip-fill', options.selectedColor);
+ attributeStyleMap.set(
'--pen-tip-border',
options.selectedColor == '#000000' ? 'currentcolor' :
options.selectedColor);
@@ -248,14 +253,12 @@ Polymer({
},
/**
- * Used to determine equality in computed bindings.
- *
- * @param {*} a
- * @param {*} b
+ * @param {string} toolName
+ * @return {boolean} Whether the annotation tool is using tool |toolName|.
+ * @private
*/
- equal_: function(a, b) {
- return a == b;
+ isAnnotationTool_: function(toolName) {
+ return !!this.annotationTool && this.annotationTool.tool === toolName;
},
-
});
})();
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn
new file mode 100644
index 00000000000..7a2ca5ce91a
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn
@@ -0,0 +1,15 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":viewer-toolbar-dropdown",
+ ]
+}
+
+js_library("viewer-toolbar-dropdown") {
+ deps = []
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
index c1964a19a20..1ebf0df604f 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -91,7 +91,7 @@
}
</style>
<cr-icon-button on-click="toggleDropdown" id="button"
- iron-icon="[[dropdownIcon]],cr:arrow-drop-down" title$="[[header]]">
+ iron-icon="[[dropdownIcon_]],cr:arrow-drop-down" title$="[[header]]">
</cr-icon-button>
<div id="container">
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
index 05f044afe47..00b2b676b45 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
@@ -18,6 +18,23 @@ Polymer({
is: 'viewer-toolbar-dropdown',
properties: {
+ /** Icon to display when the dropdown is closed. */
+ closedIcon: String,
+
+ /** Whether the dropdown should be centered or right aligned. */
+ dropdownCentered: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
+
+ /** True if the dropdown is currently open. */
+ dropdownOpen: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
+
/**
* String to be displayed at the top of the dropdown and for the tooltip
* of the button.
@@ -25,43 +42,53 @@ Polymer({
header: String,
/** Whether to hide the header at the top of the dropdown. */
- hideHeader: {type: Boolean, value: false},
-
- /** Icon to display when the dropdown is closed. */
- closedIcon: String,
+ hideHeader: {
+ type: Boolean,
+ value: false,
+ },
- /** Icon to display when the dropdown is open. */
- openIcon: String,
+ /** Lowest vertical point that the dropdown should occupy (px). */
+ lowerBound: {
+ type: Number,
+ observer: 'lowerBoundChanged_',
+ },
/** Unique id to identify this dropdown for metrics purposes. */
metricsId: String,
- /** True if the dropdown is currently open. */
- dropdownOpen: {type: Boolean, reflectToAttribute: true, value: false},
+ /** Whether the dropdown must be selected before opening. */
+ openAfterSelect: {
+ type: Boolean,
+ value: false,
+ },
- /** Whether the dropdown should be centered or right aligned. */
- dropdownCentered: {type: Boolean, reflectToAttribute: true, value: false},
+ /** Icon to display when the dropdown is open. */
+ openIcon: String,
/** Whether the dropdown is marked as selected. */
- selected: {type: Boolean, reflectToAttribute: true, value: false},
-
- /** Whether the dropdown must be selected before opening. */
- openAfterSelect: {type: Boolean, reflectToAttribute: true, value: false},
+ selected: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
- /** Toolbar icon currently being displayed. */
- dropdownIcon: {
+ /**
+ * Toolbar icon currently being displayed.
+ * @private
+ */
+ dropdownIcon_: {
type: String,
- computed: 'computeIcon_(dropdownOpen, closedIcon, openIcon)'
+ computed: 'computeIcon_(dropdownOpen, closedIcon, openIcon)',
},
-
- /** Lowest vertical point that the dropdown should occupy (px). */
- lowerBound: {type: Number, observer: 'lowerBoundChanged_'},
-
- /** Current animation being played, or null if there is none. */
- animation_: Object
},
/**
+ * Current animation being played, or null if there is none.
+ * @private {?Object}
+ */
+ animation_: null,
+
+ /**
* True if the max-height CSS property for the dropdown scroll container
* is valid. If false, the height will be updated the next time the
* dropdown is visible.
@@ -69,10 +96,15 @@ Polymer({
*/
maxHeightValid_: false,
+ /**
+ * @return {string} Current icon for the dropdown.
+ * @private
+ */
computeIcon_: function(dropdownOpen, closedIcon, openIcon) {
return dropdownOpen ? openIcon : closedIcon;
},
+ /** @private */
lowerBoundChanged_: function() {
this.maxHeightValid_ = false;
if (this.dropdownOpen) {
@@ -137,6 +169,10 @@ Polymer({
};
},
+ /**
+ * @return {!Object} Animation
+ * @private
+ */
animateEntry_: function() {
let maxHeight =
this.$.dropdown.getBoundingClientRect().height - DROPDOWN_OUTER_PADDING;
@@ -164,6 +200,10 @@ Polymer({
});
},
+ /**
+ * @return {!Object} Animation
+ * @private
+ */
animateExit_: function() {
return this.$.dropdown.animate(
[
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn
new file mode 100644
index 00000000000..4c75971c261
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn
@@ -0,0 +1,25 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":viewer-zoom-button",
+ ":viewer-zoom-toolbar",
+ ]
+}
+
+js_library("viewer-zoom-toolbar") {
+ deps = [
+ ":viewer-zoom-button",
+ "../..:pdf_fitting_type",
+ "//ui/webui/resources/js:assert",
+ "//ui/webui/resources/js:util",
+ ]
+}
+
+js_library("viewer-zoom-button") {
+ deps = []
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
index a3ae841c93f..000d098cfb3 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
@@ -19,14 +19,14 @@
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
- :host([closed]) #wrapper {
+ :host([closed_]) #wrapper {
/* 132px roughly flips the location of the button across the right edge
* of the page. */
transform: translateX(var(--translate-x-distance));
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
- :host([show-on-left][closed]) #wrapper {
+ :host([show-on-left][closed_]) #wrapper {
transform: translateX(calc(-1 * var(--translate-x-distance)));
}
@@ -76,7 +76,7 @@
}
</style>
<div id="wrapper">
- <cr-icon-button iron-icon="[[visibleIcon_]]" on-click="fireClick"
+ <cr-icon-button iron-icon="[[visibleIcon_]]" on-click="fireClick_"
aria-label$="[[visibleTooltip_]]" title="[[visibleTooltip_]]">
</cr-icon-button>
</div>
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
index 361b292e81f..2359900d83c 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js
@@ -6,6 +6,17 @@ Polymer({
is: 'viewer-zoom-button',
properties: {
+ /** Index of the icon currently being displayed. */
+ activeIndex: {
+ type: Number,
+ value: 0,
+ },
+
+ delay: {
+ type: Number,
+ observer: 'delayChanged_',
+ },
+
/**
* Icons to be displayed on the FAB. Multiple icons should be separated with
* spaces, and will be cycled through every time the FAB is clicked.
@@ -13,14 +24,6 @@ Polymer({
icons: String,
/**
- * Array version of the list of icons. Polymer does not allow array
- * properties to be set from HTML, so we must use a string property and
- * perform the conversion manually.
- * @private
- */
- icons_: {type: Array, value: [''], computed: 'computeIconsArray_(icons)'},
-
- /**
* Used to show the appropriate drop shadow when buttons are focused with
* the keyboard.
*/
@@ -29,59 +32,98 @@ Polymer({
reflectToAttribute: true,
},
- tooltips: Array,
-
- closed: {type: Boolean, reflectToAttribute: true, value: false},
+ newPrintPreview: {
+ type: Boolean,
+ reflectToAttribute: true,
+ },
- delay: {type: Number, observer: 'delayChanged_'},
+ showOnLeft: {
+ type: Boolean,
+ reflectToAttribute: true,
+ },
- newPrintPreview: {type: Boolean, reflectToAttribute: true},
+ /** @type {?Array<string>} */
+ tooltips: Array,
- showOnLeft: {type: Boolean, reflectToAttribute: true},
+ /** @private */
+ closed_: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ },
/**
- * Index of the icon currently being displayed.
+ * Array version of the list of icons. Polymer does not allow array
+ * properties to be set from HTML, so we must use a string property and
+ * perform the conversion manually.
+ * @private {!Array<string>}
*/
- activeIndex: {type: Number, value: 0},
+ icons_: {
+ type: Array,
+ value: [''],
+ computed: 'computeIconsArray_(icons)',
+ },
/**
* Icon currently being displayed on the FAB.
* @private
*/
- visibleIcon_:
- {type: String, computed: 'computeVisibleIcon_(icons_, activeIndex)'},
+ visibleIcon_: {
+ type: String,
+ computed: 'computeVisibleIcon_(icons_, activeIndex)',
+ },
+ /** @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_: function(icons) {
return icons.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_: function(icons, activeIndex) {
return icons[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_: function(tooltips, activeIndex) {
return tooltips === undefined ? '' : tooltips[activeIndex];
},
+ /** @private */
delayChanged_: function() {
this.$.wrapper.style.transitionDelay = this.delay + 'ms';
},
show: function() {
- this.closed = false;
+ this.closed_ = false;
},
hide: function() {
- this.closed = true;
+ this.closed_ = true;
},
- fireClick: function() {
+ /** @private */
+ fireClick_: function() {
// We cannot attach an on-click to the entire viewer-zoom-button, as this
// will include clicks on the margins. Instead, proxy clicks on the FAB
// through.
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
index fb817a5a01d..fe24ab64645 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js
@@ -52,6 +52,7 @@ Polymer({
return this.isPrintPreview_;
},
+ /** @return {boolean} */
isVisible: function() {
return this.visible_;
},
@@ -94,7 +95,10 @@ Polymer({
/**
* Change button tooltips to match any changes to localized strings.
- * @param {!Object} strings
+ * @param {!{tooltipFitToPage: string,
+ * tooltipFitToWidth: string,
+ * tooltipZoomIn: string,
+ * tooltipZoomOut: string}} strings
*/
setStrings: function(strings) {
this.$['fit-button'].tooltips =
@@ -103,9 +107,7 @@ Polymer({
this.$['zoom-out-button'].tooltips = [strings.tooltipZoomOut];
},
- /**
- * Handle clicks of the fit-button.
- */
+ /** Handle clicks of the fit-button. */
fitToggle: function() {
this.fireFitToChangedEvent_(
this.$['fit-button'].activeIndex == FIT_TO_WIDTH_BUTTON_STATE ?
@@ -114,9 +116,7 @@ Polymer({
true);
},
- /**
- * Handle the keyboard shortcut equivalent of fit-button clicks.
- */
+ /** Handle the keyboard shortcut equivalent of fit-button clicks. */
fitToggleFromHotKey: function() {
this.fitToggle();
@@ -130,7 +130,7 @@ Polymer({
/**
* Handle forcing zoom via scripting to a fitting type.
- * @param {FittingType} fittingType Page fitting type to force.
+ * @param {!FittingType} fittingType Page fitting type to force.
*/
forceFit: function(fittingType) {
this.fireFitToChangedEvent_(fittingType, false);
@@ -143,11 +143,11 @@ Polymer({
},
/**
- * @private
* Fire a 'fit-to-changed' {CustomEvent} with the given FittingType as detail.
- * @param {FittingType} fittingType to include as payload.
+ * @param {!FittingType} fittingType to include as payload.
* @param {boolean} userInitiated whether the event was initiated by a user
* action.
+ * @private
*/
fireFitToChangedEvent_: function(fittingType, userInitiated) {
this.fire(
diff --git a/chromium/chrome/browser/resources/pdf/index.html b/chromium/chrome/browser/resources/pdf/index.html
index c1c362756b3..06d219a6c7e 100644
--- a/chromium/chrome/browser/resources/pdf/index.html
+++ b/chromium/chrome/browser/resources/pdf/index.html
@@ -12,6 +12,8 @@
<link rel="import" href="elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html">
<link rel="import" href="elements/shared-vars.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
+ <link rel="import" href="chrome://resources/html/cr/event_target.html">
+ <link rel="import" href="chrome://resources/html/event_tracker.html">
<if expr="chromeos">
<link rel="import" href="elements/viewer-ink-host/viewer-ink-host.html">
@@ -43,7 +45,6 @@
</body>
<script src="pdf_fitting_type.js"></script>
<script src="toolbar_manager.js"></script>
-<script src="viewport_interface.js"></script>
<script src="viewport.js"></script>
<script src="open_pdf_params_parser.js"></script>
<script src="navigator.js"></script>
diff --git a/chromium/chrome/browser/resources/pdf/navigator.js b/chromium/chrome/browser/resources/pdf/navigator.js
index 0282e725de2..d2e21dde43e 100644
--- a/chromium/chrome/browser/resources/pdf/navigator.js
+++ b/chromium/chrome/browser/resources/pdf/navigator.js
@@ -5,42 +5,24 @@
'use strict';
/**
- * Creates a new NavigatorDelegate for calling browser-specific functions to
- * do the actual navigating.
- *
- * @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is
- * not displayed in a tab.
- * @constructor
+ * NavigatorDelegate for calling browser-specific functions to do the actual
+ * navigating.
*/
-function NavigatorDelegate(tabId) {
- this.tabId_ = tabId;
-}
-
-/**
- * Creates a new Navigator for navigating to links inside or outside the PDF.
- *
- * @param {string} originalUrl The original page URL.
- * @param {Object} viewport The viewport info of the page.
- * @param {Object} paramsParser The object for URL parsing.
- * @param {Object} navigatorDelegate The object with callback functions that
- * get called when navigation happens in the current tab, a new tab,
- * and a new window.
- * @constructor
- */
-function Navigator(originalUrl, viewport, paramsParser, navigatorDelegate) {
- this.originalUrl_ = originalUrl;
- this.viewport_ = viewport;
- this.paramsParser_ = paramsParser;
- this.navigatorDelegate_ = navigatorDelegate;
-}
+class NavigatorDelegate {
+ /**
+ * @param {number} tabId The tab ID of the PDF viewer or -1 if the viewer is
+ * not displayed in a tab.
+ */
+ constructor(tabId) {
+ /** @private {number} */
+ this.tabId_ = tabId;
+ }
-NavigatorDelegate.prototype = {
/**
* Called when navigation should happen in the current tab.
- *
* @param {string} url The url to be opened in the current tab.
*/
- navigateInCurrentTab: function(url) {
+ navigateInCurrentTab(url) {
// When the PDFviewer is inside a browser tab, prefer the tabs API because
// it can navigate from one file:// URL to another.
if (chrome.tabs && this.tabId_ != -1) {
@@ -48,15 +30,14 @@ NavigatorDelegate.prototype = {
} else {
window.location.href = 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: function(url, active) {
+ navigateInNewTab(url, active) {
// Prefer the tabs API because it guarantees we can just open a new tab.
// window.open doesn't have this guarantee.
if (chrome.tabs) {
@@ -64,14 +45,13 @@ NavigatorDelegate.prototype = {
} else {
window.open(url);
}
- },
+ }
/**
* Called when navigation should happen in the new window.
- *
* @param {string} url The url to be opened in the new window.
*/
- navigateInNewWindow: function(url) {
+ 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.
if (chrome.windows) {
@@ -80,52 +60,69 @@ NavigatorDelegate.prototype = {
window.open(url, '_blank');
}
}
-};
+}
-/**
- * Represents options when navigating to a new url. C++ counterpart of
- * the enum is in ui/base/window_open_disposition.h. This enum represents
- * the only values that are passed from Plugin.
- * @enum {number}
- */
-Navigator.WindowOpenDisposition = {
- CURRENT_TAB: 1,
- NEW_FOREGROUND_TAB: 3,
- NEW_BACKGROUND_TAB: 4,
- NEW_WINDOW: 6,
- SAVE_TO_DISK: 7
-};
+/** Navigator for navigating to links inside or outside the PDF. */
+class PdfNavigator {
+ /**
+ * @param {string} originalUrl The original page URL.
+ * @param {!Viewport} viewport The viewport info of the page.
+ * @param {!OpenPdfParamsParser} paramsParser The object for URL parsing.
+ * @param {!NavigatorDelegate} navigatorDelegate The object with callback
+ * functions that get called when navigation happens in the current tab,
+ * a new tab, and a new window.
+ */
+ constructor(originalUrl, viewport, paramsParser, navigatorDelegate) {
+ /** @private {?URL} */
+ this.originalUrl_ = null;
+ try {
+ this.originalUrl_ = new URL(originalUrl);
+ } catch (err) {
+ console.warn('Invalid original URL');
+ }
+
+ /** @private {!Viewport} */
+ this.viewport_ = viewport;
+
+ /** @private {!OpenPdfParamsParser} */
+ this.paramsParser_ = paramsParser;
+
+ /** @private {!NavigatorDelegate} */
+ this.navigatorDelegate_ = navigatorDelegate;
+ }
-Navigator.prototype = {
/**
* Function to navigate to the given URL. This might involve navigating
* within the PDF page or opening a new url (in the same tab or a new tab).
- *
- * @param {string} url The URL to navigate to.
- * @param {number} disposition The window open disposition when
- * navigating to the new URL.
+ * @param {string} urlString The URL to navigate to.
+ * @param {!PdfNavigator.WindowOpenDisposition} disposition The window open
+ * disposition when navigating to the new URL.
*/
- navigate: function(url, disposition) {
- if (url.length == 0) {
+ navigate(urlString, disposition) {
+ if (urlString.length == 0) {
return;
}
// If |urlFragment| starts with '#', then it's for the same URL with a
// different URL fragment.
- if (url.charAt(0) == '#') {
+ if (urlString[0] === '#' && this.originalUrl_) {
// if '#' is already present in |originalUrl| then remove old fragment
// and add new url fragment.
- const hashIndex = this.originalUrl_.search('#');
- if (hashIndex != -1) {
- url = this.originalUrl_.substring(0, hashIndex) + url;
- } else {
- url = this.originalUrl_ + url;
- }
+ const newUrl = new URL(this.originalUrl_.href);
+ newUrl.hash = urlString;
+ urlString = newUrl.href;
}
// If there's no scheme, then take a guess at the scheme.
- if (url.indexOf('://') == -1 && url.indexOf('mailto:') == -1) {
- url = this.guessUrlWithoutScheme_(url);
+ if (!urlString.includes('://') && !urlString.includes('mailto:')) {
+ urlString = this.guessUrlWithoutScheme_(urlString);
+ }
+
+ let url = null;
+ try {
+ url = new URL(urlString);
+ } catch (err) {
+ return;
}
if (!this.isValidUrl_(url)) {
@@ -133,147 +130,134 @@ Navigator.prototype = {
}
switch (disposition) {
- case Navigator.WindowOpenDisposition.CURRENT_TAB:
+ case PdfNavigator.WindowOpenDisposition.CURRENT_TAB:
this.paramsParser_.getViewportFromUrlParams(
- url, this.onViewportReceived_.bind(this));
+ url.href, this.onViewportReceived_.bind(this));
break;
- case Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
- this.navigatorDelegate_.navigateInNewTab(url, false);
+ case PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB:
+ this.navigatorDelegate_.navigateInNewTab(url.href, false);
break;
- case Navigator.WindowOpenDisposition.NEW_FOREGROUND_TAB:
- this.navigatorDelegate_.navigateInNewTab(url, true);
+ case PdfNavigator.WindowOpenDisposition.NEW_FOREGROUND_TAB:
+ this.navigatorDelegate_.navigateInNewTab(url.href, true);
break;
- case Navigator.WindowOpenDisposition.NEW_WINDOW:
- this.navigatorDelegate_.navigateInNewWindow(url);
+ case PdfNavigator.WindowOpenDisposition.NEW_WINDOW:
+ this.navigatorDelegate_.navigateInNewWindow(url.href);
break;
- case Navigator.WindowOpenDisposition.SAVE_TO_DISK:
+ case PdfNavigator.WindowOpenDisposition.SAVE_TO_DISK:
// TODO(jaepark): Alt + left clicking a link in PDF should
// download the link.
this.paramsParser_.getViewportFromUrlParams(
- url, this.onViewportReceived_.bind(this));
+ url.href, this.onViewportReceived_.bind(this));
break;
default:
break;
}
- },
+ }
/**
* Called when the viewport position is received.
- *
* @param {Object} viewportPosition Dictionary containing the viewport
* position.
* @private
*/
- onViewportReceived_: function(viewportPosition) {
- let originalUrl = this.originalUrl_;
- let hashIndex = originalUrl.search('#');
- if (hashIndex != -1) {
- originalUrl = originalUrl.substring(0, hashIndex);
- }
-
- let newUrl = viewportPosition.url;
- hashIndex = newUrl.search('#');
- if (hashIndex != -1) {
- newUrl = newUrl.substring(0, hashIndex);
+ onViewportReceived_(viewportPosition) {
+ let newUrl = null;
+ try {
+ newUrl = new URL(viewportPosition.url);
+ } catch (err) {
}
const pageNumber = viewportPosition.page;
- if (pageNumber != undefined && originalUrl == newUrl) {
+ if (pageNumber != undefined && this.originalUrl_ && newUrl &&
+ this.originalUrl_.origin === newUrl.origin &&
+ this.originalUrl_.pathname === newUrl.pathname) {
this.viewport_.goToPage(pageNumber);
} else {
this.navigatorDelegate_.navigateInCurrentTab(viewportPosition.url);
}
- },
+ }
/**
* Checks if the URL starts with a scheme and is not just a scheme.
- *
- * @param {string} url The input URL
+ * @param {!URL} url The input URL
* @return {boolean} Whether the url is valid.
* @private
*/
- isValidUrl_: function(url) {
+ isValidUrl_(url) {
// Make sure |url| starts with a valid scheme.
- if (!url.startsWith('http://') && !url.startsWith('https://') &&
- !url.startsWith('ftp://') && !url.startsWith('file://') &&
- !url.startsWith('mailto:')) {
+ const validSchemes = ['http:', 'https:', 'ftp:', 'file:', 'mailto:'];
+ if (!validSchemes.includes(url.protocol)) {
return false;
}
// Navigations to file:-URLs are only allowed from file:-URLs.
- if (url.startsWith('file:') && !this.originalUrl_.startsWith('file:')) {
- return false;
- }
-
-
- // Make sure |url| is not only a scheme.
- if (url == 'http://' || url == 'https://' || url == 'ftp://' ||
- url == 'file://' || url == 'mailto:') {
+ if (url.protocol === 'file:' && this.originalUrl_ &&
+ this.originalUrl_.protocol !== 'file:') {
return false;
}
return true;
- },
+ }
/**
* Attempt to figure out what a URL is when there is no scheme.
- *
* @param {string} url The input URL
* @return {string} The URL with a scheme or the original URL if it is not
* possible to determine the scheme.
* @private
*/
- guessUrlWithoutScheme_: function(url) {
+ guessUrlWithoutScheme_(url) {
// If the original URL is mailto:, that does not make sense to start with,
// and neither does adding |url| to it.
// If the original URL is not a valid URL, this cannot make a valid URL.
// In both cases, just bail out.
- if (this.originalUrl_.startsWith('mailto:') ||
+ if (!this.originalUrl_ || this.originalUrl_.protocol === 'mailto:' ||
!this.isValidUrl_(this.originalUrl_)) {
return url;
}
// Check for absolute paths.
if (url.startsWith('/')) {
- const schemeEndIndex = this.originalUrl_.indexOf('://');
- const firstSlash = this.originalUrl_.indexOf('/', schemeEndIndex + 3);
- // e.g. http://www.foo.com/bar -> http://www.foo.com
- const domain = firstSlash != -1 ?
- this.originalUrl_.substr(0, firstSlash) :
- this.originalUrl_;
- return domain + url;
- }
-
- // Check for obvious relative paths.
- let isRelative = false;
- if (url.startsWith('.') || url.startsWith('\\')) {
- isRelative = true;
+ return this.originalUrl_.origin + url;
}
+ // Check for other non-relative paths.
// In Adobe Acrobat Reader XI, it looks as though links with less than
// 2 dot separators in the domain are considered relative links, and
- // those with 2 of more are considered http URLs. e.g.
+ // those with 2 or more are considered http URLs. e.g.
//
// www.foo.com/bar -> http
// foo.com/bar -> relative link
- if (!isRelative) {
+ if (url.startsWith('\\')) {
+ // Prepend so that the relative URL will be correctly computed by new
+ // URL() below.
+ url = './' + url;
+ }
+ if (!url.startsWith('.')) {
const domainSeparatorIndex = url.indexOf('/');
const domainName = domainSeparatorIndex == -1 ?
url :
url.substr(0, domainSeparatorIndex);
const domainDotCount = (domainName.match(/\./g) || []).length;
- if (domainDotCount < 2) {
- isRelative = true;
+ if (domainDotCount >= 2) {
+ return 'http://' + url;
}
}
- if (isRelative) {
- const slashIndex = this.originalUrl_.lastIndexOf('/');
- const path = slashIndex != -1 ? this.originalUrl_.substr(0, slashIndex) :
- this.originalUrl_;
- return path + '/' + url;
- }
-
- return 'http://' + url;
+ return new URL(url, this.originalUrl_.href).href;
}
+}
+
+/**
+ * Represents options when navigating to a new url. C++ counterpart of
+ * the enum is in ui/base/window_open_disposition.h. This enum represents
+ * the only values that are passed from Plugin.
+ * @enum {number}
+ */
+PdfNavigator.WindowOpenDisposition = {
+ CURRENT_TAB: 1,
+ NEW_FOREGROUND_TAB: 3,
+ NEW_BACKGROUND_TAB: 4,
+ NEW_WINDOW: 6,
+ SAVE_TO_DISK: 7
};
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 aacb7c437ec..d4a502a135f 100644
--- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
+++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -2,15 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-(function() {
-
'use strict';
/**
* Parses the open pdf parameters passed in the url to set initial viewport
* settings for opening the pdf.
*/
-window.OpenPDFParamsParser = class {
+class OpenPdfParamsParser {
/**
* @param {function(Object)} postMessageCallback
* Function called to fetch information for a named destination.
@@ -206,6 +204,4 @@ window.OpenPDFParamsParser = class {
}
outstandingRequest.callback(outstandingRequest.params);
}
-};
-
-}());
+}
diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.js b/chromium/chrome/browser/resources/pdf/pdf_viewer.js
index 02763ae00c9..375663f029c 100644
--- a/chromium/chrome/browser/resources/pdf/pdf_viewer.js
+++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.js
@@ -151,7 +151,7 @@ function PDFViewer(browserApi) {
PDFMetrics.record(PDFMetrics.UserAction.DOCUMENT_OPENED);
// Parse open pdf parameters.
- this.paramsParser_ = new OpenPDFParamsParser(
+ this.paramsParser_ = new OpenPdfParamsParser(
message => this.pluginController_.postMessage(message));
const toolbarEnabled =
this.paramsParser_.getUiUrlParams(this.originalUrl_).toolbar &&
@@ -161,12 +161,13 @@ function PDFViewer(browserApi) {
// to be displayed in the window. It is sized according to the document size
// of the pdf and zoom level.
this.sizer_ = $('sizer');
+
if (this.isPrintPreview_) {
this.pageIndicator_ = $('page-indicator');
}
this.passwordScreen_ = $('password-screen');
this.passwordScreen_.addEventListener(
- 'password-submitted', this.onPasswordSubmitted_.bind(this));
+ 'password-submitted', e => this.onPasswordSubmitted_(e));
this.errorScreen_ = $('error-screen');
// Can only reload if we are in a normal tab.
if (chrome.tabs && this.browserApi_.getStreamInfo().tabId != -1) {
@@ -183,15 +184,16 @@ function PDFViewer(browserApi) {
this.browserApi_.getZoomBehavior() == BrowserApi.ZoomBehavior.MANAGE ?
this.browserApi_.getDefaultZoom() :
1.0;
- this.viewport_ = new ViewportImpl(
- window, this.sizer_, this.viewportChanged_.bind(this),
- () => this.currentController_.beforeZoom(),
- () => {
- this.currentController_.afterZoom();
- this.zoomManager_.onPdfZoomChange();
- },
- this.setUserInitiated_.bind(this), getScrollbarWidth(), defaultZoom,
- topToolbarHeight);
+ this.viewport_ = new Viewport(
+ window, this.sizer_, getScrollbarWidth(), defaultZoom, topToolbarHeight);
+ this.viewport_.setViewportChangedCallback(() => this.viewportChanged_());
+ this.viewport_.setBeforeZoomCallback(
+ () => this.currentController_.beforeZoom());
+ this.viewport_.setAfterZoomCallback(
+ () => this.currentController_.afterZoom());
+ this.viewport_.setUserInitiatedCallback(
+ userInitiated => this.setUserInitiated_(userInitiated));
+ window.addEventListener('beforeunload', () => this.viewport_.resetTracker());
// Create the plugin object dynamically so we can set its src. The plugin
// element is sized to fill the entire window and is set to be fixed
@@ -208,7 +210,7 @@ function PDFViewer(browserApi) {
// with it. We also send a message indicating that extension has loaded and
// is ready to receive messages.
window.addEventListener(
- 'message', this.handleScriptingMessage.bind(this), false);
+ 'message', message => this.handleScriptingMessage(message), false);
this.plugin_.setAttribute('src', this.originalUrl_);
this.plugin_.setAttribute(
@@ -242,20 +244,18 @@ function PDFViewer(browserApi) {
this.zoomToolbar_ = $('zoom-toolbar');
this.zoomToolbar_.setIsPrintPreview(this.isPrintPreview_);
this.zoomToolbar_.addEventListener(
- 'fit-to-changed', this.fitToChanged_.bind(this));
- this.zoomToolbar_.addEventListener(
- 'zoom-in', this.viewport_.zoomIn.bind(this.viewport_));
+ 'fit-to-changed', e => this.fitToChanged_(e));
+ this.zoomToolbar_.addEventListener('zoom-in', () => this.viewport_.zoomIn());
this.zoomToolbar_.addEventListener(
- 'zoom-out', this.viewport_.zoomOut.bind(this.viewport_));
+ 'zoom-out', () => this.viewport_.zoomOut());
this.gestureDetector_ = new GestureDetector($('content'));
this.gestureDetector_.addEventListener(
- 'pinchstart', this.onPinchStart_.bind(this));
+ 'pinchstart', e => this.onPinchStart_(e));
this.sentPinchEvent_ = false;
this.gestureDetector_.addEventListener(
- 'pinchupdate', this.onPinchUpdate_.bind(this));
- this.gestureDetector_.addEventListener(
- 'pinchend', this.onPinchEnd_.bind(this));
+ 'pinchupdate', e => this.onPinchUpdate_(e));
+ this.gestureDetector_.addEventListener('pinchend', e => this.onPinchEnd_(e));
if (toolbarEnabled) {
this.toolbar_ = $('toolbar');
@@ -293,8 +293,8 @@ function PDFViewer(browserApi) {
document.body.addEventListener('navigate', e => {
const disposition = e.detail.newtab ?
- Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
- Navigator.WindowOpenDisposition.CURRENT_TAB;
+ PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
+ PdfNavigator.WindowOpenDisposition.CURRENT_TAB;
this.navigator_.navigate(e.detail.uri, disposition);
});
@@ -309,33 +309,34 @@ function PDFViewer(browserApi) {
// Set up the ZoomManager.
this.zoomManager_ = ZoomManager.create(
- this.browserApi_.getZoomBehavior(), this.viewport_,
- this.browserApi_.setZoom.bind(this.browserApi_),
+ this.browserApi_.getZoomBehavior(), () => this.viewport_.getZoom(),
+ zoom => this.browserApi_.setZoom(zoom),
this.browserApi_.getInitialZoom());
- this.viewport_.zoomManager = this.zoomManager_;
+ this.viewport_.setZoomManager(this.zoomManager_);
this.browserApi_.addZoomEventListener(
- this.zoomManager_.onBrowserZoomChange.bind(this.zoomManager_));
+ zoom => this.zoomManager_.onBrowserZoomChange(zoom));
// Setup the keyboard event listener.
- document.addEventListener('keydown', this.handleKeyEvent_.bind(this));
- document.addEventListener('mousemove', this.handleMouseEvent_.bind(this));
- document.addEventListener('mouseout', this.handleMouseEvent_.bind(this));
+ document.addEventListener('keydown', e => this.handleKeyEvent_(e));
+ document.addEventListener('mousemove', e => this.handleMouseEvent_(e));
+ document.addEventListener('mouseout', e => this.handleMouseEvent_(e));
document.addEventListener(
- 'contextmenu', this.handleContextMenuEvent_.bind(this));
+ 'contextmenu', e => this.handleContextMenuEvent_(e));
const tabId = this.browserApi_.getStreamInfo().tabId;
- this.navigator_ = new Navigator(
+ this.navigator_ = new PdfNavigator(
this.originalUrl_, this.viewport_, this.paramsParser_,
new NavigatorDelegate(tabId));
this.viewportScroller_ =
new ViewportScroller(this.viewport_, this.plugin_, window);
// Request translated strings.
- chrome.resourcesPrivate.getStrings('pdf', this.handleStrings_.bind(this));
+ chrome.resourcesPrivate.getStrings(
+ 'pdf', strings => this.handleStrings_(strings));
// Listen for save commands from the browser.
if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) {
- chrome.mimeHandlerPrivate.onSave.addListener(this.onSave.bind(this));
+ chrome.mimeHandlerPrivate.onSave.addListener(url => this.onSave(url));
}
}
@@ -361,7 +362,7 @@ PDFViewer.prototype = {
const pageUpHandler = () => {
// Go to the previous page if we are fit-to-page or fit-to-height.
if (this.viewport_.isPagedMode()) {
- this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
+ this.viewport_.goToPreviousPage();
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
@@ -372,7 +373,7 @@ PDFViewer.prototype = {
const pageDownHandler = () => {
// Go to the next page if we are fit-to-page or fit-to-height.
if (this.viewport_.isPagedMode()) {
- this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
+ this.viewport_.goToNextPage();
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
@@ -410,7 +411,7 @@ PDFViewer.prototype = {
// no form field is focused.
if (!(this.viewport_.documentHasScrollbars().horizontal ||
this.isFormFieldFocused_)) {
- this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
+ this.viewport_.goToPreviousPage();
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
@@ -431,7 +432,7 @@ PDFViewer.prototype = {
// form field is focused.
if (!(this.viewport_.documentHasScrollbars().horizontal ||
this.isFormFieldFocused_)) {
- this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
+ this.viewport_.goToNextPage();
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
@@ -558,7 +559,7 @@ PDFViewer.prototype = {
const result = await this.inkController_.save(true);
await this.pluginController_.load(result.fileName, result.dataToSave);
// Ensure the plugin gets the initial viewport.
- this.viewport_.setZoom(this.viewport_.zoom);
+ this.pluginController_.afterZoom();
}
},
@@ -641,7 +642,8 @@ PDFViewer.prototype = {
this.isUserInitiatedEvent_ = false;
this.zoomToolbar_.forceFit(params.view);
if (params.viewPosition) {
- const zoomedPositionShift = params.viewPosition * this.viewport_.zoom;
+ const zoomedPositionShift =
+ params.viewPosition * this.viewport_.getZoom();
const currentViewportPosition = this.viewport_.position;
if (params.view == FittingType.FIT_TO_WIDTH) {
currentViewportPosition.y += zoomedPositionShift;
@@ -730,7 +732,7 @@ PDFViewer.prototype = {
this.viewport_.position = this.lastViewportPosition_;
}
this.paramsParser_.getViewportFromUrlParams(
- this.originalUrl_, this.handleURLParams_.bind(this));
+ this.originalUrl_, params => this.handleURLParams_(params));
this.setLoadState_(LoadState.SUCCESS);
this.sendDocumentLoadedMessage_();
while (this.delayedScriptingMessages_.length > 0) {
@@ -1141,7 +1143,8 @@ PDFViewer.prototype = {
handleNavigate: function(url, disposition) {
// If in print preview, always open a new tab.
if (this.isPrintPreview_) {
- this.navigator_.navigate(url, Navigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
+ this.navigator_.navigate(
+ url, PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB);
} else {
this.navigator_.navigate(url, disposition);
}
@@ -1306,7 +1309,7 @@ PDFViewer.prototype = {
setAnnotationUndoState(state) {
this.toolbar_.canUndoAnnotation = state.canUndo;
this.toolbar_.canRedoAnnotation = state.canRedo;
- }
+ },
};
/** @abstract */
@@ -1483,7 +1486,7 @@ class PluginController extends ContentController {
if (this.viewport_.pinchPhase == Viewport.PinchPhase.PINCH_START) {
const position = this.viewport_.position;
- const zoom = this.viewport_.zoom;
+ const zoom = this.viewport_.getZoom();
const pinchPhase = this.viewport_.pinchPhase;
this.postMessage({
type: 'viewport',
@@ -1503,7 +1506,7 @@ class PluginController extends ContentController {
*/
afterZoom() {
const position = this.viewport_.position;
- const zoom = this.viewport_.zoom;
+ const zoom = this.viewport_.getZoom();
const pinchVector = this.viewport_.pinchPanVector || {x: 0, y: 0};
const pinchCenter = this.viewport_.pinchCenter || {x: 0, y: 0};
const pinchPhase = this.viewport_.pinchPhase;
diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js
index 02664b3fe33..480664c014c 100644
--- a/chromium/chrome/browser/resources/pdf/viewport.js
+++ b/chromium/chrome/browser/resources/pdf/viewport.js
@@ -2,10 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/**
+ * @typedef {{
+ * width: number,
+ * height: number,
+ * pageDimensions: Array<ViewportRect>,
+ * }}
+ */
+let DocumentDimensions;
+
+/** @typedef {{x: number, y: number}} */
+let Point;
+
+/** @typedef {{width: number, height: number}} */
+let Size;
+
+/** @typedef {{x: number, y: number, width: number, height: number}} */
+let ViewportRect;
/**
* Clamps the zoom factor (or page scale factor) to be within the limits.
- *
* @param {number} factor The zoom/scale factor.
* @return {number} The factor clamped within the limits.
*/
@@ -16,30 +32,36 @@ function clampZoom(factor) {
}
/**
- * Returns the height of the intersection of two rectangles.
- *
- * @param {!ViewportRect} rect1 the first rect
- * @param {!ViewportRect} rect2 the second rect
- * @return {number} the height of the intersection of the rects
+ * @param {!ViewportRect} rect1
+ * @param {!ViewportRect} rect2
+ * @return {number} The area of the intersection of the rects
*/
-function getIntersectionHeight(rect1, rect2) {
- return Math.max(
- 0,
- Math.min(rect1.y + rect1.height, rect2.y + rect2.height) -
- Math.max(rect1.y, rect2.y));
+function getIntersectionArea(rect1, rect2) {
+ const left = Math.max(rect1.x, rect2.x);
+ const top = Math.max(rect1.y, rect2.y);
+ const right = Math.min(rect1.x + rect1.width, rect2.x + rect2.width);
+ const bottom = Math.min(rect1.y + rect1.height, rect2.y + rect2.height);
+
+ if (left >= right || top >= bottom) {
+ return 0;
+ }
+
+ return (right - left) * (bottom - top);
}
/**
- * Computes vector between two points.
- *
- * @param {!Point} p1 The first point.
- * @param {!Point} p2 The second point.
- * @return {!Point} The vector.
+ * @param {!Point} p1
+ * @param {!Point} p2
+ * @return {!Point} The vector between the two points.
*/
function vectorDelta(p1, p2) {
return {x: p2.x - p1.x, y: p2.y - p1.y};
}
+/**
+ * @param {!Point} coordinateInFrame
+ * @return {!Point} Coordinate converted to plugin coordinates.
+ */
function frameToPluginCoordinate(coordinateInFrame) {
const container = $('plugin');
return {
@@ -48,83 +70,149 @@ function frameToPluginCoordinate(coordinateInFrame) {
};
}
-/** @implements {Viewport} */
-class ViewportImpl {
+class Viewport {
/**
- * Create a new viewport.
- *
- * @param {Window} window the window
- * @param {Object} sizer is the element which represents the size of the
+ * @param {!Window} window
+ * @param {!HTMLDivElement} sizer The element which represents the size of the
* document in the viewport
- * @param {Function} viewportChangedCallback is run when the viewport changes
- * @param {Function} beforeZoomCallback is run before a change in zoom
- * @param {Function} afterZoomCallback is run after a change in zoom
- * @param {Function} setUserInitiatedCallback is run to indicate whether a
- * zoom event is user initiated.
- * @param {number} scrollbarWidth the width of scrollbars on the page
+ * @param {number} scrollbarWidth The width of scrollbars on the page
* @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.
*/
- constructor(
- window, sizer, viewportChangedCallback, beforeZoomCallback,
- afterZoomCallback, setUserInitiatedCallback, scrollbarWidth, defaultZoom,
- topToolbarHeight) {
+ constructor(window, sizer, scrollbarWidth, defaultZoom, topToolbarHeight) {
+ /** @private {!Window} */
this.window_ = window;
+
+ /** @private {!HTMLDivElement} */
this.sizer_ = sizer;
- this.viewportChangedCallback_ = viewportChangedCallback;
- this.beforeZoomCallback_ = beforeZoomCallback;
- this.afterZoomCallback_ = afterZoomCallback;
- this.setUserInitiatedCallback_ = setUserInitiatedCallback;
+
+ /** @private {number} */
+ this.scrollbarWidth_ = scrollbarWidth;
+
+ /** @private {number} */
+ this.defaultZoom_ = defaultZoom;
+
+ /** @private {number} */
+ this.topToolbarHeight_ = topToolbarHeight;
+
+ /** @private {function():void} */
+ this.viewportChangedCallback_ = function() {};
+
+ /** @private {function():void} */
+ this.beforeZoomCallback_ = function() {};
+
+ /** @private {function():void} */
+ this.afterZoomCallback_ = function() {};
+
+ /** @private {function(boolean):void} */
+ this.userInitiatedCallback_ = function() {};
+
+ /** @private {boolean} */
this.allowedToChangeZoom_ = false;
+
+ /** @private {number} */
this.internalZoom_ = 1;
- this.zoomManager_ = new InactiveZoomManager(this, 1);
+
+ /** @private {?ZoomManager} */
+ this.zoomManager_ = null;
+
/** @private {?DocumentDimensions} */
this.documentDimensions_ = null;
+
/** @private {Array<ViewportRect>} */
this.pageDimensions_ = [];
- this.scrollbarWidth_ = scrollbarWidth;
+
+ /** @private {!FittingType} */
this.fittingType_ = FittingType.NONE;
- this.defaultZoom_ = defaultZoom;
- this.topToolbarHeight_ = topToolbarHeight;
+
+ /**
+ * |twoUpView_| should be in sync with |two_up_view_| in PDFiumEngine.
+ * @private {boolean}
+ */
+ this.twoUpView_ = false;
+
+ /** @private {number} */
this.prevScale_ = 1;
+
+ /** @private {!Viewport.PinchPhase} */
this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE;
+
+ /** @private {?Point} */
this.pinchPanVector_ = null;
+
+ /** @private {?Point} */
this.pinchCenter_ = null;
+
/** @private {?Point} */
this.firstPinchCenterInFrame_ = null;
+
+ /** @private {number} */
this.rotations_ = 0;
- // TODO(dstockwell): why isn't this private?
- this.oldCenterInContent = null;
- this.keepContentCentered_ = null;
+
+ /** @private {?Point} */
+ this.oldCenterInContent_ = null;
+
+ /** @private {boolean} */
+ this.keepContentCentered_ = false;
+
+ /** @private {!EventTracker} */
+ this.tracker_ = new EventTracker();
+
+ // 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));
window.addEventListener('resize', this.resizeWrapper_.bind(this));
}
+ /** @param {function():void} viewportChangedCallback */
+ setViewportChangedCallback(viewportChangedCallback) {
+ this.viewportChangedCallback_ = viewportChangedCallback;
+ }
+
+ /** @param {function():void} beforeZoomCallback */
+ setBeforeZoomCallback(beforeZoomCallback) {
+ this.beforeZoomCallback_ = beforeZoomCallback;
+ }
+
+ /** @param {function():void} afterZoomCallback */
+ setAfterZoomCallback(afterZoomCallback) {
+ this.afterZoomCallback_ = afterZoomCallback;
+ }
+
+ /** @param {function(boolean):void} userInitiatedCallback */
+ setUserInitiatedCallback(userInitiatedCallback) {
+ this.userInitiatedCallback_ = userInitiatedCallback;
+ }
+
/**
- * @param {number} n the number of clockwise 90-degree rotations to
- * increment by.
+ * @param {number} n The number of clockwise 90-degree rotations to increment
+ * by.
*/
rotateClockwise(n) {
this.rotations_ = (this.rotations_ + n) % 4;
}
/**
- * @return {number} the number of clockwise 90-degree rotations that have been
+ * @return {number} The number of clockwise 90-degree rotations that have been
* applied.
*/
getClockwiseRotations() {
return this.rotations_;
}
+ /** @param {boolean} twoUpView The new two up view state to set. */
+ setTwoUpView(twoUpView) {
+ this.twoUpView_ = twoUpView;
+ }
+
/**
* Converts a page position (e.g. the location of a bookmark) to a screen
* position.
- *
* @param {number} page
- * @param {Point} point The position on `page`.
- * @return The screen position.
+ * @param {!Point} point The position on `page`.
+ * @return {!Point} The screen position.
*/
convertPageToScreen(page, point) {
const dimensions = this.getPageInsetDimensions(page);
@@ -168,9 +256,8 @@ class ViewportImpl {
* Rounding is necessary when interacting with the renderer which tends to
* operate in integral values (for example for determining if scrollbars
* should be shown).
- *
* @param {number} zoom The zoom to use to compute the scaled dimensions.
- * @return {Object} A dictionary with scaled 'width'/'height' of the document.
+ * @return {?Size} Scaled 'width' and 'height' of the document.
* @private
*/
getZoomedDocumentDimensions_(zoom) {
@@ -183,7 +270,7 @@ class ViewportImpl {
};
}
- /** @override */
+ /** @return {!Size} A dictionary with the 'width'/'height' of the document. */
getDocumentDimensions() {
return {
width: this.documentDimensions_.width,
@@ -192,8 +279,22 @@ class ViewportImpl {
}
/**
- * @param {number} zoom compute whether scrollbars are needed at this zoom
- * @return {{horizontal: boolean, vertical: boolean}} whether horizontal or
+ * @return {!ViewportRect} ViewportRect for the viewport given current zoom.
+ * @private
+ */
+ getViewportRect_() {
+ const zoom = this.getZoom();
+ return {
+ x: this.position.x / zoom,
+ y: this.position.y / zoom,
+ width: this.size.width / zoom,
+ height: this.size.height / zoom
+ };
+ }
+
+ /**
+ * @param {number} zoom Zoom to compute scrollbars for
+ * @return {{horizontal: boolean, vertical: boolean}} Whether horizontal or
* vertical scrollbars are needed.
* @private
*/
@@ -219,23 +320,20 @@ class ViewportImpl {
}
/**
- * Returns true if the document needs scrollbars at the current zoom level.
- *
- * @return {Object} with 'x' and 'y' keys which map to bool values
- * indicating if the horizontal and vertical scrollbars are needed
- * respectively.
+ * @return {!{horizontal: boolean, vertical: boolean}} Whether horizontal and
+ * vertical scrollbars are needed.
*/
documentHasScrollbars() {
- return this.documentNeedsScrollbars_(this.zoom);
+ return this.documentNeedsScrollbars_(this.getZoom());
}
/**
- * Helper function called when the zoomed document size changes.
- *
+ * Helper function called when the zoomed document size changes. Updates the
+ * sizer's width and height.
* @private
*/
contentSizeChanged_() {
- const zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom);
+ const zoomedDimensions = this.getZoomedDocumentDimensions_(this.getZoom());
if (zoomedDimensions) {
this.sizer_.style.width = zoomedDimensions.width + 'px';
this.sizer_.style.height =
@@ -245,7 +343,6 @@ class ViewportImpl {
/**
* Called when the viewport should be updated.
- *
* @private
*/
updateViewport_() {
@@ -254,18 +351,16 @@ class ViewportImpl {
/**
* Called when the browser window size changes.
- *
* @private
*/
resizeWrapper_() {
- this.setUserInitiatedCallback_(false);
+ this.userInitiatedCallback_(false);
this.resize_();
- this.setUserInitiatedCallback_(true);
+ this.userInitiatedCallback_(true);
}
/**
* Called when the viewport size changes.
- *
* @private
*/
resize_() {
@@ -282,7 +377,7 @@ class ViewportImpl {
}
}
- /** @override */
+ /** @return {!Point} The scroll position of the viewport. */
get position() {
return {
x: this.window_.pageXOffset,
@@ -292,16 +387,15 @@ class ViewportImpl {
/**
* Scroll the viewport to the specified position.
- *
- * @param {Point} position The position to scroll to.
+ * @param {!Point} position The position to scroll to.
*/
set position(position) {
this.window_.scrollTo(position.x, position.y + this.topToolbarHeight_);
}
- /** @override */
+ /** @return {!Size} the size of the viewport excluding scrollbars. */
get size() {
- const needsScrollbars = this.documentNeedsScrollbars_(this.zoom);
+ const needsScrollbars = this.documentNeedsScrollbars_(this.getZoom());
const scrollbarWidth = needsScrollbars.vertical ? this.scrollbarWidth_ : 0;
const scrollbarHeight =
needsScrollbars.horizontal ? this.scrollbarWidth_ : 0;
@@ -311,22 +405,25 @@ class ViewportImpl {
};
}
- /** @override */
- get zoom() {
+ /** @return {number} The current zoom. */
+ getZoom() {
return this.zoomManager_.applyBrowserZoom(this.internalZoom_);
}
- /**
- * Set the zoom manager.
- *
- * @type {ZoomManager} manager the zoom manager to set.
- */
- set zoomManager(manager) {
+ /** @param {!ZoomManager} manager */
+ setZoomManager(manager) {
+ this.resetTracker();
this.zoomManager_ = manager;
+ this.tracker_.add(
+ this.zoomManager_.getEventTarget(), 'set-zoom',
+ e => this.setZoom(e.detail));
+ this.tracker_.add(
+ this.zoomManager_.getEventTarget(), 'update-zoom-from-browser',
+ this.updateZoomFromBrowserChange_.bind(this));
}
/**
- * @return {Viewport.PinchPhase} The phase of the current pinch gesture for
+ * @return {!Viewport.PinchPhase} The phase of the current pinch gesture for
* the viewport.
*/
get pinchPhase() {
@@ -334,7 +431,7 @@ class ViewportImpl {
}
/**
- * @return {Object} The panning caused by the current pinch gesture (as
+ * @return {?Point} The panning caused by the current pinch gesture (as
* the deltas of the x and y coordinates).
*/
get pinchPanVector() {
@@ -342,7 +439,7 @@ class ViewportImpl {
}
/**
- * @return {Object} The coordinates of the center of the current pinch
+ * @return {?Point} The coordinates of the center of the current pinch
* gesture.
*/
get pinchCenter() {
@@ -354,8 +451,7 @@ class ViewportImpl {
* required so that we can notify the plugin that zooming is in progress
* so that while zooming is taking place it can stop reacting to scroll events
* from the viewport. This is to avoid flickering.
- *
- * @param {Function} f Function to wrap
+ * @param {function():void} f Function to wrap
* @private
*/
mightZoom_(f) {
@@ -364,12 +460,11 @@ class ViewportImpl {
f();
this.allowedToChangeZoom_ = false;
this.afterZoomCallback_();
+ this.zoomManager_.onPdfZoomChange();
}
/**
- * Sets the zoom of the viewport.
- *
- * @param {number} newZoom the zoom level to zoom to.
+ * @param {number} newZoom The zoom level to set.
* @private
*/
setZoomInternal_(newZoom) {
@@ -378,26 +473,27 @@ class ViewportImpl {
'Called Viewport.setZoomInternal_ without calling ' +
'Viewport.mightZoom_.');
// Record the scroll position (relative to the top-left of the window).
+ let zoom = this.getZoom();
const currentScrollPos = {
- x: this.position.x / this.zoom,
- y: this.position.y / this.zoom
+ x: this.position.x / zoom,
+ y: this.position.y / zoom
};
this.internalZoom_ = newZoom;
this.contentSizeChanged_();
// Scroll to the scaled scroll position.
+ zoom = this.getZoom();
this.position = {
- x: currentScrollPos.x * this.zoom,
- y: currentScrollPos.y * this.zoom
+ x: currentScrollPos.x * zoom,
+ y: currentScrollPos.y * zoom
};
}
/**
* Sets the zoom of the viewport.
* Same as setZoomInternal_ but for pinch zoom we have some more operations.
- *
* @param {number} scaleDelta The zoom delta.
- * @param {!Object} center The pinch center in content coordinates.
+ * @param {!Point} center The pinch center in content coordinates.
* @private
*/
setPinchZoomInternal_(scaleDelta, center) {
@@ -407,16 +503,17 @@ class ViewportImpl {
'Viewport.mightZoom_.');
this.internalZoom_ = clampZoom(this.internalZoom_ * scaleDelta);
- const newCenterInContent = this.frameToContent(center);
+ const newCenterInContent = this.frameToContent_(center);
const delta = {
- x: (newCenterInContent.x - this.oldCenterInContent.x),
- y: (newCenterInContent.y - this.oldCenterInContent.y)
+ x: (newCenterInContent.x - this.oldCenterInContent_.x),
+ y: (newCenterInContent.y - this.oldCenterInContent_.y)
};
// Record the scroll position (relative to the pinch center).
+ const zoom = this.getZoom();
const currentScrollPos = {
- x: this.position.x - delta.x * this.zoom,
- y: this.position.y - delta.y * this.zoom
+ x: this.position.x - delta.x * zoom,
+ y: this.position.y - delta.y * zoom
};
this.contentSizeChanged_();
@@ -426,24 +523,22 @@ class ViewportImpl {
/**
* Converts a point from frame to content coordinates.
- *
- * @param {!Object} framePoint The frame coordinates.
- * @return {!Object} The content coordinates.
+ * @param {!Point} framePoint The frame coordinates.
+ * @return {!Point} The content coordinates.
* @private
*/
- frameToContent(framePoint) {
+ frameToContent_(framePoint) {
// TODO(mcnee) Add a helper Point class to avoid duplicating operations
// on plain {x,y} objects.
+ const zoom = this.getZoom();
return {
- x: (framePoint.x + this.position.x) / this.zoom,
- y: (framePoint.y + this.position.y) / this.zoom
+ x: (framePoint.x + this.position.x) / zoom,
+ y: (framePoint.y + this.position.y) / zoom
};
}
/**
- * Sets the zoom to the given zoom level.
- *
- * @param {number} newZoom the zoom level to zoom to.
+ * @param {number} newZoom The zoom level to zoom to.
*/
setZoom(newZoom) {
this.fittingType_ = FittingType.NONE;
@@ -453,8 +548,12 @@ class ViewportImpl {
});
}
- /** @override */
- updateZoomFromBrowserChange(oldBrowserZoom) {
+ /**
+ * @param {!CustomEvent<number>} e Event containing the old browser zoom.
+ * @private
+ */
+ updateZoomFromBrowserChange_(e) {
+ const oldBrowserZoom = e.detail;
this.mightZoom_(() => {
// Record the scroll position (relative to the top-left of the window).
const oldZoom = oldBrowserZoom * this.internalZoom_;
@@ -463,34 +562,32 @@ class ViewportImpl {
y: this.position.y / oldZoom
};
this.contentSizeChanged_();
+ const newZoom = this.getZoom();
// Scroll to the scaled scroll position.
this.position = {
- x: currentScrollPos.x * this.zoom,
- y: currentScrollPos.y * this.zoom
+ x: currentScrollPos.x * newZoom,
+ y: currentScrollPos.y * newZoom
};
this.updateViewport_();
});
}
- /**
- * @return {number} the width of scrollbars in the viewport in pixels.
- */
+ /** @return {number} The width of scrollbars in the viewport in pixels. */
get scrollbarWidth() {
return this.scrollbarWidth_;
}
- /**
- * @return {FittingType} the fitting type the viewport is currently in.
- */
+ /** @return {FittingType} The fitting type the viewport is currently in. */
get fittingType() {
return this.fittingType_;
}
/**
- * Get the which page is at a given y position.
- *
- * @param {number} y the y-coordinate to get the page at.
- * @return {number} the index of a page overlapping the given y-coordinate.
+ * Get the page at a given y position. If there are multiple pages
+ * overlapping the given y-coordinate, return the page with the smallest
+ * index.
+ * @param {number} y The y-coordinate to get the page at.
+ * @return {number} The index of a page overlapping the given y-coordinate.
* @private
*/
getPageAtY_(y) {
@@ -521,9 +618,32 @@ class ViewportImpl {
return 0;
}
- /** @override */
+ /**
+ * Return the last page visible in the viewport. Returns the last index of the
+ * document if the viewport is below the document.
+ * @param {!ViewportRect} viewportRect
+ * @return {number} The highest index of the pages visible in the viewport.
+ * @private
+ */
+ getLastPageInViewport_(viewportRect) {
+ const pageAtY = this.getPageAtY_(viewportRect.y + viewportRect.height);
+
+ if (!this.twoUpView_ || pageAtY % 2 == 1 ||
+ pageAtY + 1 >= this.pageDimensions_.length) {
+ return pageAtY;
+ }
+
+ const nextPage = this.pageDimensions_[pageAtY + 1];
+ return getIntersectionArea(viewportRect, nextPage) > 0 ? pageAtY + 1 :
+ pageAtY;
+ }
+
+ /**
+ * @param {!Point} point
+ * @return {boolean} Whether |point| (in screen coordinates) is inside a page
+ */
isPointInsidePage(point) {
- const zoom = this.zoom;
+ const zoom = this.getZoom();
const size = this.size;
const position = this.position;
const page = this.getPageAtY_((position.y + point.y) / zoom);
@@ -544,48 +664,51 @@ class ViewportImpl {
}
/**
- * Returns the page with the greatest proportion of its height in the current
- * viewport.
- *
- * @return {number} the index of the most visible page.
+ * @return {number} The index of the page with the greatest proportion of its
+ * area in the current viewport.
*/
getMostVisiblePage() {
- const firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom);
- if (firstVisiblePage == this.pageDimensions_.length - 1) {
+ const viewportRect = this.getViewportRect_();
+
+ const firstVisiblePage = this.getPageAtY_(viewportRect.y);
+ const lastPossibleVisiblePage = this.getLastPageInViewport_(viewportRect);
+ if (firstVisiblePage === lastPossibleVisiblePage) {
return firstVisiblePage;
}
- const viewportRect = {
- x: this.position.x / this.zoom,
- y: this.position.y / this.zoom,
- width: this.size.width / this.zoom,
- height: this.size.height / this.zoom
- };
- const firstVisiblePageVisibility =
- getIntersectionHeight(
- this.pageDimensions_[firstVisiblePage], viewportRect) /
- this.pageDimensions_[firstVisiblePage].height;
- const nextPageVisibility =
- getIntersectionHeight(
- this.pageDimensions_[firstVisiblePage + 1], viewportRect) /
- this.pageDimensions_[firstVisiblePage + 1].height;
- if (nextPageVisibility > firstVisiblePageVisibility) {
- return firstVisiblePage + 1;
+ let mostVisiblePage = firstVisiblePage;
+ let largestIntersection = 0;
+
+ for (let i = firstVisiblePage; i < lastPossibleVisiblePage + 1; i++) {
+ const pageArea =
+ this.pageDimensions_[i].width * this.pageDimensions_[i].height;
+
+ // TODO(thestig): check whether we can remove this check.
+ if (pageArea <= 0) {
+ continue;
+ }
+
+ const pageIntersectionArea =
+ getIntersectionArea(this.pageDimensions_[i], viewportRect) / pageArea;
+
+ if (pageIntersectionArea > largestIntersection) {
+ mostVisiblePage = i;
+ largestIntersection = pageIntersectionArea;
+ }
}
- return firstVisiblePage;
+
+ return mostVisiblePage;
}
/**
* Compute the zoom level for fit-to-page, fit-to-width or fit-to-height.
- *
* At least one of {fitWidth, fitHeight} must be true.
- *
- * @param {Object} pageDimensions the dimensions of a given page in px.
- * @param {boolean} fitWidth a bool indicating whether the whole width of the
- * page needs to be in the viewport.
- * @param {boolean} fitHeight a bool indicating whether the whole height of
- * the page needs to be in the viewport.
- * @return {number} the internal zoom to set
+ * @param {!Size} pageDimensions The dimensions of a given page in px.
+ * @param {boolean} fitWidth Whether the whole width of the page needs to be
+ * in the viewport.
+ * @param {boolean} fitHeight Whether the whole height of the page needs to be
+ * in the viewport.
+ * @return {number} The internal zoom to set
* @private
*/
computeFittingZoom_(pageDimensions, fitWidth, fitHeight) {
@@ -644,16 +767,15 @@ class ViewportImpl {
/**
* Compute a zoom level given the dimensions to fit and the actual numbers
* in those dimensions.
- *
- * @param {boolean} fitWidth make sure the page width is totally contained in
- * the window.
- * @param {boolean} fitHeight make sure the page height is totally contained
- * in the window.
- * @param {number} windowWidth the width of the window in px.
- * @param {number} windowHeight the height of the window in px.
- * @param {number} pageWidth the width of the page in px.
- * @param {number} pageHeight the height of the page in px.
- * @return {number} the internal zoom to set
+ * @param {boolean} fitWidth Whether to constrain the page width to the
+ * window.
+ * @param {boolean} fitHeight Whether to constrain the page height to the
+ * window.
+ * @param {number} windowWidth Width of the window in px.
+ * @param {number} windowHeight Height of the window in px.
+ * @param {number} pageWidth Width of the page in px.
+ * @param {number} pageHeight Height of the page in px.
+ * @return {number} The internal zoom to set
* @private
*/
computeFittingZoomGivenDimensions_(
@@ -683,9 +805,7 @@ class ViewportImpl {
return Math.max(zoom, 0);
}
- /**
- * Zoom the viewport so that the page width consumes the entire viewport.
- */
+ /** Zoom the viewport so that the page width consumes the entire viewport. */
fitToWidth() {
this.mightZoom_(() => {
this.fittingType_ = FittingType.FIT_TO_WIDTH;
@@ -702,7 +822,6 @@ class ViewportImpl {
/**
* Zoom the viewport so that the page height consumes the entire viewport.
- *
* @param {boolean} scrollToTopOfPage Set to true if the viewport should be
* scrolled to the top of the current page. Set to false if the viewport
* should remain at the current scroll position.
@@ -723,25 +842,25 @@ class ViewportImpl {
};
this.setZoomInternal_(this.computeFittingZoom_(dimensions, false, true));
if (scrollToTopOfPage) {
- this.position = {x: 0, y: this.pageDimensions_[page].y * this.zoom};
+ this.position = {
+ x: 0,
+ y: this.pageDimensions_[page].y * this.getZoom()
+ };
}
this.updateViewport_();
});
}
- /**
- * Zoom the viewport so that the page height consumes the entire viewport.
- */
+ /** Zoom the viewport so that the page height consumes the entire viewport. */
fitToHeight() {
this.fitToHeightInternal_(true);
}
/**
* Zoom the viewport so that a page consumes as much as possible of the it.
- *
- * @param {boolean} scrollToTopOfPage Set to true if the viewport should be
- * scrolled to the top of the current page. Set to false if the viewport
- * should remain at the current scroll position.
+ * @param {boolean} scrollToTopOfPage Whether the viewport should be scrolled
+ * to the top of the current page. If false, the viewport will remain at
+ * the current scroll position.
* @private
*/
fitToPageInternal_(scrollToTopOfPage) {
@@ -758,7 +877,10 @@ class ViewportImpl {
};
this.setZoomInternal_(this.computeFittingZoom_(dimensions, true, true));
if (scrollToTopOfPage) {
- this.position = {x: 0, y: this.pageDimensions_[page].y * this.zoom};
+ this.position = {
+ x: 0,
+ y: this.pageDimensions_[page].y * this.getZoom()
+ };
}
this.updateViewport_();
});
@@ -772,9 +894,7 @@ class ViewportImpl {
this.fitToPageInternal_(true);
}
- /**
- * Zoom the viewport to the default zoom policy.
- */
+ /** Zoom the viewport to the default zoom. */
fitToNone() {
this.mightZoom_(() => {
this.fittingType_ = FittingType.NONE;
@@ -788,9 +908,7 @@ class ViewportImpl {
});
}
- /**
- * Zoom out to the next predefined zoom level.
- */
+ /** Zoom out to the next predefined zoom level. */
zoomOut() {
this.mightZoom_(() => {
this.fittingType_ = FittingType.NONE;
@@ -805,9 +923,7 @@ class ViewportImpl {
});
}
- /**
- * Zoom in to the next predefined zoom level.
- */
+ /** Zoom in to the next predefined zoom level. */
zoomIn() {
this.mightZoom_(() => {
this.fittingType_ = FittingType.NONE;
@@ -824,7 +940,6 @@ class ViewportImpl {
/**
* Pinch zoom event handler.
- *
* @param {!Object} e The pinch event.
*/
pinchZoom(e) {
@@ -857,8 +972,8 @@ class ViewportImpl {
y: this.window_.innerHeight / 2
};
} else if (this.keepContentCentered_) {
- this.oldCenterInContent =
- this.frameToContent(frameToPluginCoordinate(e.center));
+ this.oldCenterInContent_ =
+ this.frameToContent_(frameToPluginCoordinate(e.center));
this.keepContentCentered_ = false;
}
@@ -872,10 +987,10 @@ class ViewportImpl {
pinchZoomStart(e) {
this.pinchPhase_ = Viewport.PinchPhase.PINCH_START;
this.prevScale_ = 1;
- this.oldCenterInContent =
- this.frameToContent(frameToPluginCoordinate(e.center));
+ this.oldCenterInContent_ =
+ this.frameToContent_(frameToPluginCoordinate(e.center));
- const needsScrollbars = this.documentNeedsScrollbars_(this.zoom);
+ const needsScrollbars = this.documentNeedsScrollbars_(this.getZoom());
this.keepContentCentered_ = !needsScrollbars.horizontal;
// We keep track of begining of the pinch.
// By doing so we will be able to compute the pan distance.
@@ -887,7 +1002,7 @@ class ViewportImpl {
this.mightZoom_(() => {
this.pinchPhase_ = Viewport.PinchPhase.PINCH_END;
const scaleDelta = e.startScaleRatio / this.prevScale_;
- this.pinchCenter_ = e.center;
+ this.pinchCenter_ = /** @type {!Point} */ (e.center);
this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center));
this.updateViewport_();
@@ -900,8 +1015,32 @@ class ViewportImpl {
}
/**
+ * Go to the next page. If the document is in two-up view, go to the left page
+ * of the next row.
+ */
+ goToNextPage() {
+ const currentPage = this.getMostVisiblePage();
+ const nextPageOffset = (this.twoUpView_ && currentPage % 2 == 0) ? 2 : 1;
+ this.goToPage(currentPage + nextPageOffset);
+ }
+
+ /**
+ * Go to the previous page. If the document is in two-up view, go to the left
+ * page of the previous row.
+ */
+ goToPreviousPage() {
+ const currentPage = this.getMostVisiblePage();
+ let previousPageOffset = -1;
+
+ if (this.twoUpView_) {
+ previousPageOffset = (currentPage % 2 == 0) ? -2 : -3;
+ }
+
+ this.goToPage(currentPage + previousPageOffset);
+ }
+
+ /**
* Go to the given page index.
- *
* @param {number} page the index of the page to go to. zero-based.
*/
goToPage(page) {
@@ -910,7 +1049,6 @@ class ViewportImpl {
/**
* Go to the given y position in the given page index.
- *
* @param {number} page the index of the page to go to. zero-based.
* @param {number} x the x position in the page to go to.
* @param {number} y the y position in the page to go to.
@@ -935,17 +1073,15 @@ class ViewportImpl {
toolbarOffset = this.topToolbarHeight_;
}
this.position = {
- x: (dimensions.x + x) * this.zoom,
- y: (dimensions.y + y) * this.zoom - toolbarOffset
+ x: (dimensions.x + x) * this.getZoom(),
+ y: (dimensions.y + y) * this.getZoom() - toolbarOffset
};
this.updateViewport_();
});
}
/**
- * Set the dimensions of the document.
- *
- * @param {DocumentDimensions} documentDimensions the dimensions of the
+ * @param {DocumentDimensions} documentDimensions The dimensions of the
* document
*/
setDocumentDimensions(documentDimensions) {
@@ -982,9 +1118,8 @@ class ViewportImpl {
/**
* Get the coordinates of the page contents (excluding the page shadow)
* relative to the screen.
- *
- * @param {number} page the index of the page to get the rect for.
- * @return {Object} a rect representing the page in screen coordinates.
+ * @param {number} page The index of the page to get the rect for.
+ * @return {!ViewportRect} A rect representing the page in screen coordinates.
*/
getPageScreenRect(page) {
if (!this.documentDimensions_) {
@@ -1006,24 +1141,23 @@ class ViewportImpl {
Viewport.PAGE_SHADOW.left;
// Compute the space on the left of the document if the document fits
// completely in the screen.
+ const zoom = this.getZoom();
let spaceOnLeft =
- (this.size.width - this.documentDimensions_.width * this.zoom) / 2;
+ (this.size.width - this.documentDimensions_.width * zoom) / 2;
spaceOnLeft = Math.max(spaceOnLeft, 0);
return {
- x: x * this.zoom + spaceOnLeft - this.window_.pageXOffset,
- y: insetDimensions.y * this.zoom - this.window_.pageYOffset,
- width: insetDimensions.width * this.zoom,
- height: insetDimensions.height * this.zoom
+ x: x * zoom + spaceOnLeft - this.window_.pageXOffset,
+ y: insetDimensions.y * zoom - this.window_.pageYOffset,
+ width: insetDimensions.width * zoom,
+ height: insetDimensions.height * zoom
};
}
/**
* Check if the current fitting type is a paged mode.
- *
* In a paged mode, page up and page down scroll to the top of the
* previous/next page and part of the page is under the toolbar.
- *
* @return {boolean} Whether the current fitting type is a paged mode.
*/
isPagedMode() {
@@ -1032,11 +1166,7 @@ class ViewportImpl {
this.fittingType_ == FittingType.FIT_TO_HEIGHT);
}
- /**
- * Scroll the viewport to the specified position.
- *
- * @param {!Point} point The position to which to move the viewport.
- */
+ /** @param {!Point} point The position to which to scroll the viewport. */
scrollTo(point) {
let changed = false;
const newPosition = this.position;
@@ -1054,15 +1184,64 @@ class ViewportImpl {
}
}
- /**
- * Scroll the viewport by the specified delta.
- *
- * @param {!Point} delta The delta by which to move the viewport.
- */
+ /** @param {!Point} delta The delta by which to scroll the viewport. */
scrollBy(delta) {
const newPosition = this.position;
newPosition.x += delta.x;
newPosition.y += delta.y;
this.scrollTo(newPosition);
}
+
+ /** Removes all events being tracked from the tracker. */
+ resetTracker() {
+ if (this.tracker_) {
+ this.tracker_.removeAll();
+ }
+ }
}
+
+/**
+ * Enumeration of pinch states.
+ * This should match PinchPhase enum in pdf/out_of_process_instance.h
+ * @enum {number}
+ */
+Viewport.PinchPhase = {
+ PINCH_NONE: 0,
+ PINCH_START: 1,
+ PINCH_UPDATE_ZOOM_OUT: 2,
+ PINCH_UPDATE_ZOOM_IN: 3,
+ PINCH_END: 4
+};
+
+/**
+ * The increment to scroll a page by in pixels when up/down/left/right arrow
+ * keys are pressed. Usually we just let the browser handle scrolling on the
+ * window when these keys are pressed but in certain cases we need to simulate
+ * these events.
+ */
+Viewport.SCROLL_INCREMENT = 40;
+
+/**
+ * Predefined zoom factors to be used when zooming in/out. These are in
+ * ascending order. This should match the lists in
+ * components/zoom/page_zoom_constants.h and
+ * chrome/browser/resources/settings/appearance_page/appearance_page.js
+ */
+Viewport.ZOOM_FACTORS = [
+ 0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3,
+ 4, 5
+];
+
+/** The minimum and maximum range to be used to clip zoom factor. */
+Viewport.ZOOM_FACTOR_RANGE = {
+ min: Viewport.ZOOM_FACTORS[0],
+ max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1]
+};
+
+/** The width of the page shadow around pages in pixels. */
+Viewport.PAGE_SHADOW = {
+ top: 3,
+ bottom: 7,
+ left: 5,
+ right: 5
+};
diff --git a/chromium/chrome/browser/resources/pdf/viewport_interface.js b/chromium/chrome/browser/resources/pdf/viewport_interface.js
deleted file mode 100644
index c9f99aceb2f..00000000000
--- a/chromium/chrome/browser/resources/pdf/viewport_interface.js
+++ /dev/null
@@ -1,136 +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.
-
-/**
- * @typedef {{
- * width: number,
- * height: number,
- * pageDimensions: Array<ViewportRect>,
- * }}
- */
-let DocumentDimensions;
-
-/**
- * @typedef {{
- * x: number,
- * y: number
- * }}
- */
-let Point;
-
-/**
- * @typedef {{
- * width: number,
- * height: number,
- * }}
- */
-let Size;
-
-/**
- * @typedef {{
- * x: number,
- * y: number,
- * width: number,
- * height: number,
- * }}
- */
-let ViewportRect;
-
-/**
- * @interface
- */
-class Viewport {
- /**
- * Returns the document dimensions.
- *
- * @return {!Size} A dictionary with the 'width'/'height' of the document.
- */
- getDocumentDimensions() {}
-
- /**
- * @return {!Point} the scroll position of the viewport.
- */
- get position() {}
-
- /**
- * @return {!Size} the size of the viewport excluding scrollbars.
- */
- get size() {}
-
- /**
- * @return {number} the zoom level of the viewport.
- */
- get zoom() {}
-
- /**
- * Sets the zoom to the given zoom level.
- *
- * @param {number} newZoom the zoom level to zoom to.
- */
- setZoom(newZoom) {}
-
- /**
- * Gets notified of the browser zoom changing separately from the
- * internal zoom.
- *
- * @param {number} oldBrowserZoom the previous value of the browser zoom.
- */
- updateZoomFromBrowserChange(oldBrowserZoom) {}
-
- /**
- * @param {!Point} point
- * @return {boolean} Whether |point| (in screen coordinates) is inside a page
- */
- isPointInsidePage(point) {}
-}
-
-/**
- * Enumeration of pinch states.
- * This should match PinchPhase enum in pdf/out_of_process_instance.h
- * @enum {number}
- */
-Viewport.PinchPhase = {
- PINCH_NONE: 0,
- PINCH_START: 1,
- PINCH_UPDATE_ZOOM_OUT: 2,
- PINCH_UPDATE_ZOOM_IN: 3,
- PINCH_END: 4
-};
-
-/**
- * The increment to scroll a page by in pixels when up/down/left/right arrow
- * keys are pressed. Usually we just let the browser handle scrolling on the
- * window when these keys are pressed but in certain cases we need to simulate
- * these events.
- */
-Viewport.SCROLL_INCREMENT = 40;
-
-/**
- * Predefined zoom factors to be used when zooming in/out. These are in
- * ascending order. This should match the lists in
- * components/ui/zoom/page_zoom_constants.h and
- * chrome/browser/resources/settings/appearance_page/appearance_page.js
- */
-Viewport.ZOOM_FACTORS = [
- 0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3,
- 4, 5
-];
-
-/**
- * The minimum and maximum range to be used to clip zoom factor.
- */
-Viewport.ZOOM_FACTOR_RANGE = {
- min: Viewport.ZOOM_FACTORS[0],
- max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1]
-};
-
-/**
- * The width of the page shadow around pages in pixels.
- */
-Viewport.PAGE_SHADOW = {
- top: 3,
- bottom: 7,
- left: 5,
- right: 5
-};
diff --git a/chromium/chrome/browser/resources/pdf/zoom_manager.js b/chromium/chrome/browser/resources/pdf/zoom_manager.js
index 6c3182d3fd1..db2878dd3d9 100644
--- a/chromium/chrome/browser/resources/pdf/zoom_manager.js
+++ b/chromium/chrome/browser/resources/pdf/zoom_manager.js
@@ -11,35 +11,50 @@
*/
class ZoomManager {
/**
- * @param {!Viewport} viewport A Viewport for which to manage zoom.
+ * @param {function():number} getViewportZoom Callback to get the viewport's
+ * current zoom level.
* @param {number} initialZoom The initial browser zoom level.
*/
- constructor(viewport, initialZoom) {
+ constructor(getViewportZoom, initialZoom) {
if (this.constructor === ZoomManager) {
throw new TypeError('Instantiated abstract class: ZoomManager');
}
- this.viewport_ = viewport;
+
+ /** @private {number} */
this.browserZoom_ = initialZoom;
+
+ /** @private {function():number} */
+ this.getViewportZoom_ = getViewportZoom;
+
+ /** @private {!EventTarget} */
+ this.eventTarget_ = new cr.EventTarget();
+ }
+
+ /** @return {!EventTarget} */
+ getEventTarget() {
+ return this.eventTarget_;
}
/**
* Creates the appropriate kind of zoom manager given the zoom behavior.
*
* @param {BrowserApi.ZoomBehavior} zoomBehavior How to manage zoom.
- * @param {!Viewport} viewport A Viewport for which to manage zoom.
- * @param {Function} setBrowserZoomFunction A function that sets the browser
- * zoom to the provided value.
+ * @param {function():number} getViewportZoom A function that gets the current
+ * viewport zoom.
+ * @param {function(number):Promise} setBrowserZoomFunction A function that
+ * sets the browser zoom to the provided value.
* @param {number} initialZoom The initial browser zoom level.
*/
- static create(zoomBehavior, viewport, setBrowserZoomFunction, initialZoom) {
+ static create(
+ zoomBehavior, getViewportZoom, setBrowserZoomFunction, initialZoom) {
switch (zoomBehavior) {
case BrowserApi.ZoomBehavior.MANAGE:
return new ActiveZoomManager(
- viewport, setBrowserZoomFunction, initialZoom);
+ getViewportZoom, setBrowserZoomFunction, initialZoom);
case BrowserApi.ZoomBehavior.PROPAGATE_PARENT:
- return new EmbeddedZoomManager(viewport, initialZoom);
+ return new EmbeddedZoomManager(getViewportZoom, initialZoom);
default:
- return new InactiveZoomManager(viewport, initialZoom);
+ return new InactiveZoomManager(getViewportZoom, initialZoom);
}
}
@@ -104,15 +119,19 @@ class InactiveZoomManager extends ZoomManager {}
class ActiveZoomManager extends ZoomManager {
/**
* Constructs a ActiveZoomManager.
- *
- * @param {!Viewport} viewport A Viewport for which to manage zoom.
- * @param {Function} setBrowserZoomFunction A function that sets the browser
- * zoom to the provided value.
+ * @param {function():number} getViewportZoom A function that gets the current
+ * viewport zoom level
+ * @param {function(number):Promise} setBrowserZoomFunction A function that
+ * sets the browser zoom to the provided value.
* @param {number} initialZoom The initial browser zoom level.
*/
- constructor(viewport, setBrowserZoomFunction, initialZoom) {
- super(viewport, initialZoom);
+ constructor(getViewportZoom, setBrowserZoomFunction, initialZoom) {
+ super(getViewportZoom, initialZoom);
+
+ /** @private {function(number):Promise} */
this.setBrowserZoomFunction_ = setBrowserZoomFunction;
+
+ /** @private {?Promise} */
this.changingBrowserZoom_ = null;
}
@@ -135,11 +154,13 @@ class ActiveZoomManager extends ZoomManager {
}
this.browserZoom_ = newZoom;
- this.viewport_.setZoom(newZoom);
+ this.eventTarget_.dispatchEvent(
+ new CustomEvent('set-zoom', {detail: newZoom}));
}
/**
* Invoked when an extension-initiated zoom-level change occurs.
+ * @override
*/
onPdfZoomChange() {
// If we are already changing the browser zoom level in response to a
@@ -150,20 +171,21 @@ class ActiveZoomManager extends ZoomManager {
return;
}
- const zoom = this.viewport_.zoom;
- if (this.floatingPointEquals(this.browserZoom_, zoom)) {
+ const viewportZoom = this.getViewportZoom_();
+ if (this.floatingPointEquals(this.browserZoom_, viewportZoom)) {
return;
}
- this.changingBrowserZoom_ = this.setBrowserZoomFunction_(zoom).then(() => {
- this.browserZoom_ = zoom;
- this.changingBrowserZoom_ = null;
+ this.changingBrowserZoom_ =
+ this.setBrowserZoomFunction_(viewportZoom).then(() => {
+ this.browserZoom_ = viewportZoom;
+ this.changingBrowserZoom_ = null;
- // The extension's zoom level may have changed while the browser zoom
- // change was in progress. We call back into onPdfZoomChange to ensure
- // the browser zoom is up to date.
- this.onPdfZoomChange();
- });
+ // The extension's zoom level may have changed while the browser zoom
+ // change was in progress. We call back into onPdfZoomChange to ensure
+ // the browser zoom is up to date.
+ this.onPdfZoomChange();
+ });
}
/**
@@ -206,6 +228,7 @@ class EmbeddedZoomManager extends ZoomManager {
onBrowserZoomChange(newZoom) {
const oldZoom = this.browserZoom_;
this.browserZoom_ = newZoom;
- this.viewport_.updateZoomFromBrowserChange(oldZoom);
+ this.eventTarget_.dispatchEvent(
+ new CustomEvent('update-zoom-from-browser', {detail: oldZoom}));
}
}
diff --git a/chromium/chrome/browser/resources/policy/policy.css b/chromium/chrome/browser/resources/policy/policy.css
index 67d7f688746..3f9e034434b 100644
--- a/chromium/chrome/browser/resources/policy/policy.css
+++ b/chromium/chrome/browser/resources/policy/policy.css
@@ -86,8 +86,9 @@ body > main {
flex-grow: 1;
max-height: 200px;
overflow: auto;
+ overflow-wrap: break-word;
text-overflow: unset;
- white-space: pre;
+ white-space: pre-wrap;
}
<if expr="not is_android">
@@ -124,11 +125,11 @@ div.status-entry:last-child {
}
body > header {
+ align-items: center;
padding: 12px;
}
-body > header,
-.reload-show-unset-section {
+.header-row {
align-items: center;
display: flex;
height: 56px;
@@ -219,4 +220,4 @@ body > main {
display: block;
flex: 1;
}
-</if> \ No newline at end of file
+</if>
diff --git a/chromium/chrome/browser/resources/policy/policy.html b/chromium/chrome/browser/resources/policy/policy.html
index b059bc46a4e..efcbbe51d73 100644
--- a/chromium/chrome/browser/resources/policy/policy.html
+++ b/chromium/chrome/browser/resources/policy/policy.html
@@ -18,13 +18,13 @@
<body>
<header>
- <h1>$i18n{title}</h1>
- <input id="filter" class="search-field-container" type="search"
- placeholder="$i18n{filterPlaceholder}"
- aria-label="$i18n{filterPlaceholder}" incremental>
- </header>
- <main id="policy-ui">
- <section class="reload-show-unset-section">
+ <div class="header-row">
+ <h1>$i18n{title}</h1>
+ <input id="filter" class="search-field-container" type="search"
+ placeholder="$i18n{filterPlaceholder}"
+ aria-label="$i18n{filterPlaceholder}" incremental>
+ </div>
+ <div class="header-row">
<button id="reload-policies">$i18n{reloadPolicies}</button>
<button id="export-policies">$i18n{exportPoliciesJSON}</button>
<div id="show-unset-container" class="show-unset-checkbox">
@@ -33,7 +33,9 @@
<span>$i18n{showUnset}</span>
</label>
</div>
- </section>
+ </div>
+ </header>
+ <main id="policy-ui">
<section id="status-section" class="status-box-section" hidden>
<h3>$i18n{status}</h3>
<div id="status-box-container"></div>
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.js b/chromium/chrome/browser/resources/print_preview/data/destination.js
index d037df020f5..403becbf6d1 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination.js
@@ -2,248 +2,246 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/**
- * Enumeration of the types of destinations.
- * @enum {string}
- */
-print_preview.DestinationType = {
- GOOGLE: 'google',
- GOOGLE_PROMOTED: 'google_promoted',
- LOCAL: 'local',
- MOBILE: 'mobile'
-};
-
-/**
- * Enumeration of the origin types for cloud destinations.
- * @enum {string}
- */
-print_preview.DestinationOrigin = {
- LOCAL: 'local',
- COOKIES: 'cookies',
- // <if expr="chromeos">
- DEVICE: 'device',
- // </if>
- PRIVET: 'privet',
- EXTENSION: 'extension',
- CROS: 'chrome_os',
-};
-
-/**
- * Cloud Print origins.
- * @const {!Array<!print_preview.DestinationOrigin>}
- */
-print_preview.CloudOrigins = [
- print_preview.DestinationOrigin.COOKIES,
+cr.define('print_preview', function() {
+ 'use strict';
+
+ /**
+ * Enumeration of the types of destinations.
+ * @enum {string}
+ */
+ const DestinationType = {
+ GOOGLE: 'google',
+ GOOGLE_PROMOTED: 'google_promoted',
+ LOCAL: 'local',
+ MOBILE: 'mobile',
+ };
+
+ /**
+ * Enumeration of the origin types for cloud destinations.
+ * @enum {string}
+ */
+ const DestinationOrigin = {
+ LOCAL: 'local',
+ COOKIES: 'cookies',
+ // <if expr="chromeos">
+ DEVICE: 'device',
+ // </if>
+ PRIVET: 'privet',
+ EXTENSION: 'extension',
+ CROS: 'chrome_os',
+ };
+
+ /**
+ * Cloud Print origins.
+ * @const {!Array<!print_preview.DestinationOrigin>}
+ */
+ const CloudOrigins = [
+ DestinationOrigin.COOKIES,
+ // <if expr="chromeos">
+ DestinationOrigin.DEVICE,
+ // </if>
+ ];
+
+ /**
+ * Enumeration of the connection statuses of printer destinations.
+ * @enum {string}
+ */
+ const DestinationConnectionStatus = {
+ DORMANT: 'DORMANT',
+ OFFLINE: 'OFFLINE',
+ ONLINE: 'ONLINE',
+ UNKNOWN: 'UNKNOWN',
+ UNREGISTERED: 'UNREGISTERED',
+ };
+
+ /**
+ * Enumeration specifying whether a destination is provisional and the reason
+ * the destination is provisional.
+ * @enum {string}
+ */
+ const DestinationProvisionalType = {
+ // Destination is not provisional.
+ NONE: 'NONE',
+ // User has to grant USB access for the destination to its provider.
+ // Used for destinations with extension origin.
+ NEEDS_USB_PERMISSION: 'NEEDS_USB_PERMISSION',
+ };
+
+ /**
+ * Enumeration specifying the status of a destination's 2018 certificate.
+ * Values UNKNOWN and YES are returned directly by the GCP server.
+ * @enum {string}
+ */
+ const DestinationCertificateStatus = {
+ // Destination is not a cloud printer or no status was retrieved.
+ NONE: 'NONE',
+ // Printer does not have a valid 2018 certificate. Currently unused, to be
+ // sent by GCP server.
+ NO: 'NO',
+ // Printer may or may not have a valid certificate. Sent by GCP server.
+ UNKNOWN: 'UNKNOWN',
+ // Printer has a valid 2018 certificate. Sent by GCP server.
+ YES: 'YES',
+ };
+
+ /**
+ * @typedef {{
+ * display_name: (string),
+ * type: (string | undefined),
+ * value: (number | string | boolean),
+ * is_default: (boolean | undefined),
+ * }}
+ */
+ let VendorCapabilitySelectOption;
+
+ /**
+ * Specifies a custom vendor capability.
+ * @typedef {{
+ * id: (string),
+ * display_name: (string),
+ * localized_display_name: (string | undefined),
+ * type: (string),
+ * select_cap: ({
+ * option: (Array<!print_preview.VendorCapabilitySelectOption>|undefined),
+ * }|undefined),
+ * typed_value_cap: ({
+ * default: (number | string | boolean | undefined),
+ * }|undefined),
+ * range_cap: ({
+ * default: (number),
+ * }),
+ * }}
+ */
+ let VendorCapability;
+
+ /**
+ * Capabilities of a print destination represented in a CDD.
+ * Pin capability is not a part of standard CDD description and is defined
+ * only on Chrome OS.
+ *
+ * @typedef {{
+ * vendor_capability: !Array<!print_preview.VendorCapability>,
+ * collate: ({default: (boolean|undefined)}|undefined),
+ * color: ({
+ * option: !Array<{
+ * type: (string|undefined),
+ * vendor_id: (string|undefined),
+ * custom_display_name: (string|undefined),
+ * is_default: (boolean|undefined)
+ * }>
+ * }|undefined),
+ * copies: ({default: (number|undefined),
+ * max: (number|undefined)}|undefined),
+ * duplex: ({option: !Array<{type: (string|undefined),
+ * is_default: (boolean|undefined)}>}|undefined),
+ * page_orientation: ({
+ * option: !Array<{type: (string|undefined),
+ * is_default: (boolean|undefined)}>
+ * }|undefined),
+ * media_size: ({
+ * option: !Array<{
+ * type: (string|undefined),
+ * vendor_id: (string|undefined),
+ * custom_display_name: (string|undefined),
+ * is_default: (boolean|undefined)
+ * }>
+ * }|undefined),
+ * dpi: ({
+ * option: !Array<{
+ * vendor_id: (string|undefined),
+ * horizontal_dpi: number,
+ * vertical_dpi: number,
+ * is_default: (boolean|undefined)
+ * }>
+ * }|undefined),
+ * pin: ({supported: (boolean|undefined)}|undefined)
+ * }}
+ */
+ let CddCapabilities;
+
+ /**
+ * The CDD (Cloud Device Description) describes the capabilities of a print
+ * destination.
+ *
+ * @typedef {{
+ * version: string,
+ * printer: !print_preview.CddCapabilities,
+ * }}
+ */
+ let Cdd;
+
+ /**
+ * Enumeration of color modes used by Chromium.
+ * @enum {number}
+ */
+ const ColorMode = {
+ GRAY: 1,
+ COLOR: 2,
+ };
+
// <if expr="chromeos">
- print_preview.DestinationOrigin.DEVICE
+ /**
+ * Enumeration of color mode restrictions used by Chromium.
+ * This has to coincide with |printing::ColorModeRestriction| as defined in
+ * printing/backend/printing_restrictions.h
+ * @enum {number}
+ */
+ const ColorModeRestriction = {
+ UNSET: 0x0,
+ MONOCHROME: 0x1,
+ COLOR: 0x2,
+ };
+
+ /**
+ * Enumeration of duplex mode restrictions used by Chromium.
+ * This has to coincide with |printing::DuplexModeRestriction| as defined in
+ * printing/backend/printing_restrictions.h
+ * @enum {number}
+ */
+ const DuplexModeRestriction = {
+ UNSET: 0x0,
+ SIMPLEX: 0x1,
+ LONG_EDGE: 0x2,
+ SHORT_EDGE: 0x4,
+ DUPLEX: 0x6,
+ };
+
+ /**
+ * Enumeration of PIN printing mode restrictions used by Chromium.
+ * This has to coincide with |printing::PinModeRestriction| as defined in
+ * printing/backend/printing_restrictions.h
+ * @enum {number}
+ */
+ const PinModeRestriction = {
+ UNSET: 0,
+ PIN: 1,
+ NO_PIN: 2,
+ };
+
+ /**
+ * Policies affecting a destination.
+ * @typedef {{
+ * allowedColorModes: ?print_preview.ColorModeRestriction,
+ * allowedDuplexModes: ?print_preview.DuplexModeRestriction,
+ * allowedPinMode: ?print_preview.PinModeRestriction,
+ * defaultColorMode: ?print_preview.ColorModeRestriction,
+ * defaultDuplexMode: ?print_preview.DuplexModeRestriction,
+ * defaultPinMode: ?print_preview.PinModeRestriction,
+ * }}
+ */
+ let Policies;
// </if>
-];
-
-/**
- * Enumeration of the connection statuses of printer destinations.
- * @enum {string}
- */
-print_preview.DestinationConnectionStatus = {
- DORMANT: 'DORMANT',
- OFFLINE: 'OFFLINE',
- ONLINE: 'ONLINE',
- UNKNOWN: 'UNKNOWN',
- UNREGISTERED: 'UNREGISTERED'
-};
-
-/**
- * Enumeration specifying whether a destination is provisional and the reason
- * the destination is provisional.
- * @enum {string}
- */
-print_preview.DestinationProvisionalType = {
- // Destination is not provisional.
- NONE: 'NONE',
- // User has to grant USB access for the destination to its provider.
- // Used for destinations with extension origin.
- NEEDS_USB_PERMISSION: 'NEEDS_USB_PERMISSION'
-};
-
-/**
- * Enumeration specifying the status of a destination's 2018 certificate.
- * Values UNKNOWN and YES are returned directly by the GCP server.
- * @enum {string}
- */
-print_preview.DestinationCertificateStatus = {
- // Destination is not a cloud printer or no status was retrieved.
- NONE: 'NONE',
- // Printer does not have a valid 2018 certificate. Currently unused, to be
- // sent by GCP server.
- NO: 'NO',
- // Printer may or may not have a valid certificate. Sent by GCP server.
- UNKNOWN: 'UNKNOWN',
- // Printer has a valid 2018 certificate. Sent by GCP server.
- YES: 'YES'
-};
-
-/**
- * @typedef {{
- * display_name: (string),
- * type: (string | undefined),
- * value: (number | string | boolean),
- * is_default: (boolean | undefined),
- * }}
- */
-print_preview.VendorCapabilitySelectOption;
-
-/**
- * Specifies a custom vendor capability.
- * @typedef {{
- * id: (string),
- * display_name: (string),
- * localized_display_name: (string | undefined),
- * type: (string),
- * select_cap: ({
- * option: (Array<!print_preview.VendorCapabilitySelectOption>|undefined),
- * }|undefined),
- * typed_value_cap: ({
- * default: (number | string | boolean | undefined),
- * }|undefined),
- * range_cap: ({
- * default: (number),
- * }),
- * }}
- */
-print_preview.VendorCapability;
-
-/**
- * Capabilities of a print destination represented in a CDD.
- * Pin capability is not a part of standard CDD description and is defined only
- * on Chrome OS.
- *
- * @typedef {{
- * vendor_capability: !Array<!print_preview.VendorCapability>,
- * collate: ({default: (boolean|undefined)}|undefined),
- * color: ({
- * option: !Array<{
- * type: (string|undefined),
- * vendor_id: (string|undefined),
- * custom_display_name: (string|undefined),
- * is_default: (boolean|undefined)
- * }>
- * }|undefined),
- * copies: ({default: (number|undefined),
- * max: (number|undefined)}|undefined),
- * duplex: ({option: !Array<{type: (string|undefined),
- * is_default: (boolean|undefined)}>}|undefined),
- * page_orientation: ({
- * option: !Array<{type: (string|undefined),
- * is_default: (boolean|undefined)}>
- * }|undefined),
- * media_size: ({
- * option: !Array<{
- * type: (string|undefined),
- * vendor_id: (string|undefined),
- * custom_display_name: (string|undefined),
- * is_default: (boolean|undefined)
- * }>
- * }|undefined),
- * dpi: ({
- * option: !Array<{
- * vendor_id: (string|undefined),
- * horizontal_dpi: number,
- * vertical_dpi: number,
- * is_default: (boolean|undefined)
- * }>
- * }|undefined),
- * pin: ({supported: (boolean|undefined)}|undefined)
- * }}
- */
-print_preview.CddCapabilities;
-
-/**
- * The CDD (Cloud Device Description) describes the capabilities of a print
- * destination.
- *
- * @typedef {{
- * version: string,
- * printer: !print_preview.CddCapabilities,
- * }}
- */
-print_preview.Cdd;
-
-/**
- * Enumeration of color modes used by Chromium.
- * @enum {number}
- */
-print_preview.ColorMode = {
- GRAY: 1,
- COLOR: 2
-};
-
-// <if expr="chromeos">
-/**
- * Enumeration of color mode restrictions used by Chromium.
- * This has to coincide with |printing::ColorModeRestriction| as defined in
- * printing/backend/printing_restrictions.h
- * @enum {number}
- */
-print_preview.ColorModeRestriction = {
- UNSET: 0x0,
- MONOCHROME: 0x1,
- COLOR: 0x2,
-};
-
-/**
- * Enumeration of duplex mode restrictions used by Chromium.
- * This has to coincide with |printing::DuplexModeRestriction| as defined in
- * printing/backend/printing_restrictions.h
- * @enum {number}
- */
-print_preview.DuplexModeRestriction = {
- UNSET: 0x0,
- SIMPLEX: 0x1,
- LONG_EDGE: 0x2,
- SHORT_EDGE: 0x4,
- DUPLEX: 0x6
-};
-
-/**
- * Enumeration of PIN printing mode restrictions used by Chromium.
- * This has to coincide with |printing::PinModeRestriction| as defined in
- * printing/backend/printing_restrictions.h
- * @enum {number}
- */
-print_preview.PinModeRestriction = {
- UNSET: 0,
- PIN: 1,
- NO_PIN: 2
-};
-
-/**
- * Policies affecting a destination.
- * @typedef {{
- * allowedColorModes: ?print_preview.ColorModeRestriction,
- * allowedDuplexModes: ?print_preview.DuplexModeRestriction,
- * allowedPinMode: ?print_preview.PinModeRestriction,
- * defaultColorMode: ?print_preview.ColorModeRestriction,
- * defaultDuplexMode: ?print_preview.DuplexModeRestriction,
- * defaultPinMode: ?print_preview.PinModeRestriction,
- * }}
- */
-print_preview.Policies;
-// </if>
-
-/**
- * @typedef {{id: string,
- * origin: print_preview.DestinationOrigin,
- * account: string,
- * capabilities: ?print_preview.Cdd,
- * displayName: string,
- * extensionId: string,
- * extensionName: string}}
- */
-print_preview.RecentDestination;
-cr.define('print_preview', function() {
- 'use strict';
+ /**
+ * @typedef {{id: string,
+ * origin: print_preview.DestinationOrigin,
+ * account: string,
+ * capabilities: ?print_preview.Cdd,
+ * displayName: string,
+ * extensionId: string,
+ * extensionName: string}}
+ */
+ let RecentDestination;
/**
* Creates a |RecentDestination| to represent |destination| in the app
@@ -430,7 +428,7 @@ cr.define('print_preview', function() {
* @private {print_preview.DestinationProvisionalType}
*/
this.provisionalType_ = (opt_params && opt_params.provisionalType) ||
- print_preview.DestinationProvisionalType.NONE;
+ DestinationProvisionalType.NONE;
/**
* Printer 2018 certificate status
@@ -441,8 +439,7 @@ cr.define('print_preview', function() {
assert(
this.provisionalType_ !=
- print_preview.DestinationProvisionalType
- .NEEDS_USB_PERMISSION ||
+ DestinationProvisionalType.NEEDS_USB_PERMISSION ||
this.isExtension,
'Provisional USB destination only supprted with extension origin.');
@@ -499,17 +496,16 @@ cr.define('print_preview', function() {
/** @return {boolean} Whether the destination is local or cloud-based. */
get isLocal() {
- return this.origin_ == print_preview.DestinationOrigin.LOCAL ||
- this.origin_ == print_preview.DestinationOrigin.EXTENSION ||
- this.origin_ == print_preview.DestinationOrigin.CROS ||
- (this.origin_ == print_preview.DestinationOrigin.PRIVET &&
- this.connectionStatus_ !=
- print_preview.DestinationConnectionStatus.UNREGISTERED);
+ return this.origin_ == DestinationOrigin.LOCAL ||
+ this.origin_ == DestinationOrigin.EXTENSION ||
+ this.origin_ == DestinationOrigin.CROS ||
+ (this.origin_ == DestinationOrigin.PRIVET &&
+ this.connectionStatus_ != DestinationConnectionStatus.UNREGISTERED);
}
/** @return {boolean} Whether the destination is a Privet local printer */
get isPrivet() {
- return this.origin_ == print_preview.DestinationOrigin.PRIVET;
+ return this.origin_ == DestinationOrigin.PRIVET;
}
/**
@@ -517,7 +513,7 @@ cr.define('print_preview', function() {
* printer.
*/
get isExtension() {
- return this.origin_ == print_preview.DestinationOrigin.EXTENSION;
+ return this.origin_ == DestinationOrigin.EXTENSION;
}
/**
@@ -671,8 +667,7 @@ cr.define('print_preview', function() {
/** @return {boolean} Whether the destination is ready to be selected. */
get readyForSelection() {
- return (!cr.isChromeOS ||
- this.origin_ != print_preview.DestinationOrigin.CROS ||
+ return (!cr.isChromeOS || this.origin_ != DestinationOrigin.CROS ||
this.capabilities_ != null) &&
!this.isProvisional;
}
@@ -776,8 +771,7 @@ cr.define('print_preview', function() {
* @return {boolean}
*/
get isProvisional() {
- return this.provisionalType_ !=
- print_preview.DestinationProvisionalType.NONE;
+ return this.provisionalType_ != DestinationProvisionalType.NONE;
}
/**
@@ -957,9 +951,28 @@ cr.define('print_preview', function() {
// Export
return {
- Destination: Destination,
- makeRecentDestination: makeRecentDestination,
+ CddCapabilities: CddCapabilities,
+ Cdd: Cdd,
+ CloudOrigins: CloudOrigins,
+ ColorMode: ColorMode,
createDestinationKey: createDestinationKey,
createRecentDestinationKey: createRecentDestinationKey,
+ DestinationCertificateStatus: DestinationCertificateStatus,
+ DestinationConnectionStatus: DestinationConnectionStatus,
+ Destination: Destination,
+ DestinationOrigin: DestinationOrigin,
+ DestinationProvisionalType: DestinationProvisionalType,
+ DestinationType: DestinationType,
+ makeRecentDestination: makeRecentDestination,
+ RecentDestination: RecentDestination,
+ VendorCapabilitySelectOption: VendorCapabilitySelectOption,
+ VendorCapability: VendorCapability,
+
+ // <if expr="chromeos">
+ ColorModeRestriction: ColorModeRestriction,
+ DuplexModeRestriction: DuplexModeRestriction,
+ PinModeRestriction: PinModeRestriction,
+ Policies: Policies,
+ // </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 61402a2561f..b5e767f25d9 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination_store.js
@@ -2,32 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/**
- * Printer search statuses used by the destination store.
- * @enum {string}
- */
-print_preview.DestinationStorePrinterSearchStatus = {
- START: 'start',
- SEARCHING: 'searching',
- DONE: 'done'
-};
-
-/**
- * Enumeration of possible destination errors.
- * @enum {number}
- */
-print_preview.DestinationErrorType = {
- INVALID: 0,
- UNSUPPORTED: 1,
- // <if expr="chromeos">
- NO_DESTINATIONS: 2,
- // </if>
-};
-
cr.define('print_preview', function() {
'use strict';
+
+ /**
+ * Printer search statuses used by the destination store.
+ * @enum {string}
+ */
+ const DestinationStorePrinterSearchStatus = {
+ START: 'start',
+ SEARCHING: 'searching',
+ DONE: 'done'
+ };
+
+ /**
+ * Enumeration of possible destination errors.
+ * @enum {number}
+ */
+ const DestinationErrorType = {
+ INVALID: 0,
+ UNSUPPORTED: 1,
+ // <if expr="chromeos">
+ NO_DESTINATIONS: 2,
+ // </if>
+ };
+
/**
* Localizes printer capabilities.
* @param {!print_preview.Cdd} capabilities Printer capabilities to
@@ -191,20 +190,20 @@ cr.define('print_preview', function() {
* Whether a search for destinations is in progress for each type of
* printer.
* @private {!Map<!print_preview.PrinterType,
- * !print_preview.DestinationStorePrinterSearchStatus>}
+ * !DestinationStorePrinterSearchStatus>}
*/
this.destinationSearchStatus_ = new Map([
[
print_preview.PrinterType.EXTENSION_PRINTER,
- print_preview.DestinationStorePrinterSearchStatus.START
+ DestinationStorePrinterSearchStatus.START
],
[
print_preview.PrinterType.PRIVET_PRINTER,
- print_preview.DestinationStorePrinterSearchStatus.START
+ DestinationStorePrinterSearchStatus.START
],
[
print_preview.PrinterType.LOCAL_PRINTER,
- print_preview.DestinationStorePrinterSearchStatus.START
+ DestinationStorePrinterSearchStatus.START
],
]);
@@ -301,10 +300,7 @@ cr.define('print_preview', function() {
get isPrintDestinationSearchInProgress() {
const isLocalDestinationSearchInProgress =
Array.from(this.destinationSearchStatus_.values())
- .some(
- el => el ===
- print_preview.DestinationStorePrinterSearchStatus
- .SEARCHING);
+ .some(el => el === DestinationStorePrinterSearchStatus.SEARCHING);
if (isLocalDestinationSearchInProgress) {
return true;
}
@@ -824,18 +820,18 @@ cr.define('print_preview', function() {
*/
startLoadDestinations_(type) {
if (this.destinationSearchStatus_.get(type) ===
- print_preview.DestinationStorePrinterSearchStatus.DONE) {
+ DestinationStorePrinterSearchStatus.DONE) {
return;
}
this.destinationSearchStatus_.set(
- type, print_preview.DestinationStorePrinterSearchStatus.SEARCHING);
+ type, DestinationStorePrinterSearchStatus.SEARCHING);
this.nativeLayer_.getPrinters(type).then(
this.onDestinationSearchDone_.bind(this, type), () => {
// Will be rejected by C++ for privet printers if privet printing
// is disabled.
assert(type === print_preview.PrinterType.PRIVET_PRINTER);
this.destinationSearchStatus_.set(
- type, print_preview.DestinationStorePrinterSearchStatus.DONE);
+ type, DestinationStorePrinterSearchStatus.DONE);
});
}
@@ -870,7 +866,7 @@ cr.define('print_preview', function() {
// Add cloud printer to the map.
this.destinationSearchStatus_.set(
print_preview.PrinterType.CLOUD_PRINTER,
- print_preview.DestinationStorePrinterSearchStatus.START);
+ DestinationStorePrinterSearchStatus.START);
types.push(print_preview.PrinterType.CLOUD_PRINTER);
} else {
this.startLoadCloudDestinations();
@@ -1144,7 +1140,7 @@ cr.define('print_preview', function() {
*/
onDestinationSearchDone_(type) {
this.destinationSearchStatus_.set(
- type, print_preview.DestinationStorePrinterSearchStatus.DONE);
+ type, DestinationStorePrinterSearchStatus.DONE);
this.dispatchEvent(
new CustomEvent(DestinationStore.EventType.DESTINATION_SEARCH_DONE));
if (type === print_preview.PrinterType.EXTENSION_PRINTER) {
@@ -1184,6 +1180,9 @@ cr.define('print_preview', function() {
assert(settingsInfo.printer)));
}
if (dest) {
+ if (settingsInfo.printer && settingsInfo.printer.policies) {
+ dest.policies = settingsInfo.printer.policies;
+ }
if ((origin === print_preview.DestinationOrigin.LOCAL ||
origin === print_preview.DestinationOrigin.CROS) &&
dest.capabilities) {
@@ -1258,9 +1257,7 @@ cr.define('print_preview', function() {
sendNoPrinterEventIfNeeded_() {
const isLocalDestinationSearchNotStarted =
Array.from(this.destinationSearchStatus_.values())
- .some(
- el => el ===
- print_preview.DestinationStorePrinterSearchStatus.START);
+ .some(el => el === DestinationStorePrinterSearchStatus.START);
if (isLocalDestinationSearchNotStarted ||
this.isPrintDestinationSearchInProgress ||
!this.selectFirstDestination_) {
@@ -1554,5 +1551,8 @@ cr.define('print_preview', function() {
};
// Export
- return {DestinationStore: DestinationStore};
+ return {
+ DestinationErrorType: DestinationErrorType,
+ DestinationStore: DestinationStore,
+ };
});
diff --git a/chromium/chrome/browser/resources/print_preview/data/invitation_store.js b/chromium/chrome/browser/resources/print_preview/data/invitation_store.js
index 724a309540f..253e442420d 100644
--- a/chromium/chrome/browser/resources/print_preview/data/invitation_store.js
+++ b/chromium/chrome/browser/resources/print_preview/data/invitation_store.js
@@ -2,21 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/**
- * @enum {number}
- * @private
- */
-print_preview.InvitationStoreLoadStatus = {
- IN_PROGRESS: 1,
- DONE: 2,
- FAILED: 3
-};
-
cr.define('print_preview', function() {
'use strict';
+ /**
+ * @enum {number}
+ * @private
+ */
+ const InvitationStoreLoadStatus = {
+ IN_PROGRESS: 1,
+ DONE: 2,
+ FAILED: 3,
+ };
+
class InvitationStore extends cr.EventTarget {
/** Printer sharing invitations data store. */
constructor() {
@@ -31,7 +29,7 @@ cr.define('print_preview', function() {
/**
* Maps user account to the flag whether the invitations for this account
* were successfully loaded.
- * @private {!Object<print_preview.InvitationStoreLoadStatus>}
+ * @private {!Object<InvitationStoreLoadStatus>}
*/
this.loadStatus_ = {};
@@ -109,16 +107,14 @@ cr.define('print_preview', function() {
return;
}
if (this.loadStatus_.hasOwnProperty(user)) {
- if (this.loadStatus_[user] ==
- print_preview.InvitationStoreLoadStatus.DONE) {
+ if (this.loadStatus_[user] == InvitationStoreLoadStatus.DONE) {
this.dispatchEvent(new CustomEvent(
InvitationStore.EventType.INVITATION_SEARCH_DONE));
}
return;
}
- this.loadStatus_[user] =
- print_preview.InvitationStoreLoadStatus.IN_PROGRESS;
+ this.loadStatus_[user] = InvitationStoreLoadStatus.IN_PROGRESS;
this.cloudPrintInterface_.invites(user);
}
@@ -159,8 +155,7 @@ cr.define('print_preview', function() {
* @private
*/
onCloudPrintInvitesDone_(event) {
- this.loadStatus_[event.detail.user] =
- print_preview.InvitationStoreLoadStatus.DONE;
+ this.loadStatus_[event.detail.user] = InvitationStoreLoadStatus.DONE;
this.invitations_[event.detail.user] = event.detail.invitations;
this.dispatchEvent(
@@ -174,8 +169,7 @@ cr.define('print_preview', function() {
* @private
*/
onCloudPrintInvitesFailed_(event) {
- this.loadStatus_[event.detail] =
- print_preview.InvitationStoreLoadStatus.FAILED;
+ this.loadStatus_[event.detail] = InvitationStoreLoadStatus.FAILED;
}
/**
diff --git a/chromium/chrome/browser/resources/print_preview/data/margins.js b/chromium/chrome/browser/resources/print_preview/data/margins.js
index 389e4e05961..3facd5a82cd 100644
--- a/chromium/chrome/browser/resources/print_preview/data/margins.js
+++ b/chromium/chrome/browser/resources/print_preview/data/margins.js
@@ -2,45 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview.ticket_items');
-/**
- * Enumeration of the orientations of margins.
- * @enum {string}
- */
-print_preview.ticket_items.CustomMarginsOrientation = {
- TOP: 'top',
- RIGHT: 'right',
- BOTTOM: 'bottom',
- LEFT: 'left'
-};
+cr.define('print_preview.ticket_items', function() {
+ 'use strict';
+
+ /**
+ * Enumeration of the orientations of margins.
+ * @enum {string}
+ */
+ const CustomMarginsOrientation = {
+ TOP: 'top',
+ RIGHT: 'right',
+ BOTTOM: 'bottom',
+ LEFT: 'left',
+ };
-/**
- * Must be kept in sync with the C++ MarginType enum in
- * printing/print_job_constants.h.
- * @enum {number}
- */
-print_preview.ticket_items.MarginsTypeValue = {
- DEFAULT: 0,
- NO_MARGINS: 1,
- MINIMUM: 2,
- CUSTOM: 3
-};
+ /**
+ * Must be kept in sync with the C++ MarginType enum in
+ * printing/print_job_constants.h.
+ * @enum {number}
+ */
+ const MarginsTypeValue = {
+ DEFAULT: 0,
+ NO_MARGINS: 1,
+ MINIMUM: 2,
+ CUSTOM: 3,
+ };
-/**
- * Keep in sync with the C++ kSettingMargin... values in
- * printing/print_job_constants.h.
- * @typedef {{
- * marginTop: number,
- * marginRight: number,
- * marginBottom: number,
- * marginLeft: number,
- * }}
- */
-print_preview.MarginsSetting;
+ return {
+ CustomMarginsOrientation: CustomMarginsOrientation,
+ MarginsTypeValue: MarginsTypeValue,
+ };
+});
cr.define('print_preview', function() {
'use strict';
+ /**
+ * Keep in sync with the C++ kSettingMargin... values in
+ * printing/print_job_constants.h.
+ * @typedef {{
+ * marginTop: number,
+ * marginRight: number,
+ * marginBottom: number,
+ * marginLeft: number,
+ * }}
+ */
+ let MarginsSetting;
+
class Margins {
/**
* Creates a Margins object that holds four margin values in points.
@@ -144,5 +152,8 @@ cr.define('print_preview', function() {
}
// Export
- return {Margins: Margins};
+ return {
+ Margins: Margins,
+ MarginsSetting: MarginsSetting,
+ };
});
diff --git a/chromium/chrome/browser/resources/print_preview/data/measurement_system.js b/chromium/chrome/browser/resources/print_preview/data/measurement_system.js
index aa422f2c77f..c57e8a90e29 100644
--- a/chromium/chrome/browser/resources/print_preview/data/measurement_system.js
+++ b/chromium/chrome/browser/resources/print_preview/data/measurement_system.js
@@ -2,55 +2,53 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/**
- * Enumeration of measurement unit types.
- * @enum {number}
- */
-print_preview.MeasurementSystemUnitType = {
- METRIC: 0, // millimeters
- IMPERIAL: 1 // inches
-};
-
-/**
- * @typedef {{precision: number,
- * decimalPlaces: number,
- * ptsPerUnit: number,
- * unitSymbol: string}}
- */
-print_preview.MeasurementSystemPrefs;
-
cr.define('print_preview', function() {
'use strict';
+ /**
+ * Enumeration of measurement unit types.
+ * @enum {number}
+ */
+ const MeasurementSystemUnitType = {
+ METRIC: 0, // millimeters
+ IMPERIAL: 1 // inches
+ };
+
+ /**
+ * @typedef {{precision: number,
+ * decimalPlaces: number,
+ * ptsPerUnit: number,
+ * unitSymbol: string}}
+ */
+ let MeasurementSystemPrefs;
+
class MeasurementSystem {
/**
* Measurement system of the print preview. Used to parse and serialize
* point measurements into the system's local units (e.g. millimeters,
* inches).
- * @param {string} thousandsDelimeter Delimeter between thousands digits.
- * @param {string} decimalDelimeter Delimeter between integers and decimals.
+ * @param {string} thousandsDelimiter Delimiter between thousands digits.
+ * @param {string} decimalDelimiter Delimiter between integers and decimals.
* @param {!print_preview.MeasurementSystemUnitType} unitType Measurement
* unit type of the system.
*/
- constructor(thousandsDelimeter, decimalDelimeter, unitType) {
+ constructor(thousandsDelimiter, decimalDelimiter, unitType) {
/**
- * The thousands delimeter to use when displaying numbers.
+ * The thousands delimiter to use when displaying numbers.
* @private {string}
*/
- this.thousandsDelimeter_ = thousandsDelimeter || ',';
+ this.thousandsDelimiter_ = thousandsDelimiter || ',';
/**
- * The decimal delimeter to use when displaying numbers.
+ * The decimal delimiter to use when displaying numbers.
* @private {string}
*/
- this.decimalDelimeter_ = decimalDelimeter || '.';
+ this.decimalDelimiter_ = decimalDelimiter || '.';
assert(measurementSystemPrefs.has(unitType));
/**
* The measurement system preferences based on the unit type.
- * @private {!print_preview.MeasurementSystemPrefs}
+ * @private {!MeasurementSystemPrefs}
*/
this.measurementSystemPrefs_ = measurementSystemPrefs.get(unitType);
}
@@ -61,19 +59,19 @@ cr.define('print_preview', function() {
}
/**
- * @return {string} The thousands delimeter character of the measurement
+ * @return {string} The thousands delimiter character of the measurement
* system.
*/
- get thousandsDelimeter() {
- return this.thousandsDelimeter_;
+ get thousandsDelimiter() {
+ return this.thousandsDelimiter_;
}
/**
- * @return {string} The decimal delimeter character of the measurement
+ * @return {string} The decimal delimiter character of the measurement
* system.
*/
- get decimalDelimeter() {
- return this.decimalDelimeter_;
+ get decimalDelimiter() {
+ return this.decimalDelimiter_;
}
/**
@@ -108,11 +106,11 @@ cr.define('print_preview', function() {
/**
* Maximum resolution and number of decimal places for local unit values.
* @private {!Map<!print_preview.MeasurementSystemUnitType,
- * !print_preview.MeasurementSystemPrefs>}
+ * !MeasurementSystemPrefs>}
*/
const measurementSystemPrefs = new Map([
[
- print_preview.MeasurementSystemUnitType.METRIC, {
+ MeasurementSystemUnitType.METRIC, {
precision: 0.5,
decimalPlaces: 1,
ptsPerUnit: 72.0 / 25.4,
@@ -120,11 +118,14 @@ cr.define('print_preview', function() {
}
],
[
- print_preview.MeasurementSystemUnitType.IMPERIAL,
+ MeasurementSystemUnitType.IMPERIAL,
{precision: 0.01, decimalPlaces: 2, ptsPerUnit: 72.0, unitSymbol: '"'}
]
]);
// Export
- return {MeasurementSystem: MeasurementSystem};
+ return {
+ MeasurementSystem: MeasurementSystem,
+ MeasurementSystemUnitType: MeasurementSystemUnitType,
+ };
});
diff --git a/chromium/chrome/browser/resources/print_preview/data/model.js b/chromium/chrome/browser/resources/print_preview/data/model.js
index a576e86a07b..4e5182375ae 100644
--- a/chromium/chrome/browser/resources/print_preview/data/model.js
+++ b/chromium/chrome/browser/resources/print_preview/data/model.js
@@ -2,117 +2,127 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
+cr.define('print_preview', function() {
+ /**
+ * |key| is the field in the serialized settings state that corresponds to the
+ * setting, or an empty string if the setting should not be saved in the
+ * serialized state.
+ * @typedef {{
+ * value: *,
+ * unavailableValue: *,
+ * valid: boolean,
+ * available: boolean,
+ * setByPolicy: boolean,
+ * setFromUi: boolean,
+ * key: string,
+ * updatesPreview: boolean,
+ * }}
+ */
+ let Setting;
-/**
- * |key| is the field in the serialized settings state that corresponds to the
- * setting, or an empty string if the setting should not be saved in the
- * serialized state.
- * @typedef {{
- * value: *,
- * unavailableValue: *,
- * valid: boolean,
- * available: boolean,
- * setByPolicy: boolean,
- * setFromUi: boolean,
- * key: string,
- * updatesPreview: boolean,
- * }}
- */
-print_preview.Setting;
+ /**
+ * @typedef {{
+ * pages: !print_preview.Setting,
+ * copies: !print_preview.Setting,
+ * collate: !print_preview.Setting,
+ * layout: !print_preview.Setting,
+ * color: !print_preview.Setting,
+ * mediaSize: !print_preview.Setting,
+ * margins: !print_preview.Setting,
+ * dpi: !print_preview.Setting,
+ * fitToPage: !print_preview.Setting,
+ * scaling: !print_preview.Setting,
+ * duplex: !print_preview.Setting,
+ * duplexShortEdge: !print_preview.Setting,
+ * cssBackground: !print_preview.Setting,
+ * selectionOnly: !print_preview.Setting,
+ * headerFooter: !print_preview.Setting,
+ * rasterize: !print_preview.Setting,
+ * vendorItems: !print_preview.Setting,
+ * otherOptions: !print_preview.Setting,
+ * ranges: !print_preview.Setting,
+ * pagesPerSheet: !print_preview.Setting,
+ * pin: (print_preview.Setting|undefined),
+ * pinValue: (print_preview.Setting|undefined),
+ * }}
+ */
+ let Settings;
-/**
- * @typedef {{
- * pages: !print_preview.Setting,
- * copies: !print_preview.Setting,
- * collate: !print_preview.Setting,
- * layout: !print_preview.Setting,
- * color: !print_preview.Setting,
- * mediaSize: !print_preview.Setting,
- * margins: !print_preview.Setting,
- * dpi: !print_preview.Setting,
- * fitToPage: !print_preview.Setting,
- * scaling: !print_preview.Setting,
- * duplex: !print_preview.Setting,
- * duplexShortEdge: !print_preview.Setting,
- * cssBackground: !print_preview.Setting,
- * selectionOnly: !print_preview.Setting,
- * headerFooter: !print_preview.Setting,
- * rasterize: !print_preview.Setting,
- * vendorItems: !print_preview.Setting,
- * otherOptions: !print_preview.Setting,
- * ranges: !print_preview.Setting,
- * pagesPerSheet: !print_preview.Setting,
- * pin: (print_preview.Setting|undefined),
- * pinValue: (print_preview.Setting|undefined),
- * }}
- */
-print_preview.Settings;
+ /**
+ * @typedef {{
+ * version: string,
+ * recentDestinations: (!Array<!print_preview.RecentDestination> |
+ * undefined),
+ * dpi: ({horizontal_dpi: number,
+ * vertical_dpi: number,
+ * is_default: (boolean | undefined)} | undefined),
+ * mediaSize: ({height_microns: number,
+ * width_microns: number,
+ * custom_display_name: (string | undefined),
+ * is_default: (boolean | undefined)} | undefined),
+ * marginsType: (print_preview.ticket_items.MarginsTypeValue | undefined),
+ * customMargins: (print_preview.MarginsSetting | undefined),
+ * isColorEnabled: (boolean | undefined),
+ * isDuplexEnabled: (boolean | undefined),
+ * isHeaderFooterEnabled: (boolean | undefined),
+ * isLandscapeEnabled: (boolean | undefined),
+ * isCollateEnabled: (boolean | undefined),
+ * isFitToPageEnabled: (boolean | undefined),
+ * isCssBackgroundEnabled: (boolean | undefined),
+ * scaling: (string | undefined),
+ * vendor_options: (Object | undefined),
+ * isPinEnabled: (boolean | undefined),
+ * pinValue: (string | undefined)
+ * }}
+ */
+ let SerializedSettings;
-/**
- * @typedef {{
- * version: string,
- * recentDestinations: (!Array<!print_preview.RecentDestination> |
- * undefined),
- * dpi: ({horizontal_dpi: number,
- * vertical_dpi: number,
- * is_default: (boolean | undefined)} | undefined),
- * mediaSize: ({height_microns: number,
- * width_microns: number,
- * custom_display_name: (string | undefined),
- * is_default: (boolean | undefined)} | undefined),
- * marginsType: (print_preview.ticket_items.MarginsTypeValue | undefined),
- * customMargins: (print_preview.MarginsSetting | undefined),
- * isColorEnabled: (boolean | undefined),
- * isDuplexEnabled: (boolean | undefined),
- * isHeaderFooterEnabled: (boolean | undefined),
- * isLandscapeEnabled: (boolean | undefined),
- * isCollateEnabled: (boolean | undefined),
- * isFitToPageEnabled: (boolean | undefined),
- * isCssBackgroundEnabled: (boolean | undefined),
- * scaling: (string | undefined),
- * vendor_options: (Object | undefined),
- * isPinEnabled: (boolean | undefined),
- * pinValue: (string | undefined)
- * }}
- */
-print_preview.SerializedSettings;
+ /**
+ * @typedef {{
+ * value: *,
+ * managed: boolean
+ * }}
+ */
+ let PolicyEntry;
-/**
- * @typedef {{
- * value: *,
- * managed: boolean
- * }}
- */
-print_preview.PolicyEntry;
+ /**
+ * @typedef {{
+ * headerFooter: print_preview.PolicyEntry
+ * }}
+ */
+ let PolicySettings;
-/**
- * @typedef {{
- * headerFooter: print_preview.PolicyEntry
- * }}
- */
-print_preview.PolicySettings;
+ /**
+ * Constant values matching printing::DuplexMode enum.
+ * @enum {number}
+ */
+ const DuplexMode = {
+ SIMPLEX: 0,
+ LONG_EDGE: 1,
+ SHORT_EDGE: 2,
+ UNKNOWN_DUPLEX_MODE: -1,
+ };
-/**
- * Constant values matching printing::DuplexMode enum.
- * @enum {number}
- */
-print_preview.DuplexMode = {
- SIMPLEX: 0,
- LONG_EDGE: 1,
- SHORT_EDGE: 2,
- UNKNOWN_DUPLEX_MODE: -1,
-};
+ /**
+ * Values matching the types of duplex in a CDD.
+ * @enum {string}
+ */
+ const DuplexType = {
+ NO_DUPLEX: 'NO_DUPLEX',
+ LONG_EDGE: 'LONG_EDGE',
+ SHORT_EDGE: 'SHORT_EDGE'
+ };
-/**
- * Values matching the types of duplex in a CDD.
- * @enum {string}
- */
-print_preview.DuplexType = {
- NO_DUPLEX: 'NO_DUPLEX',
- LONG_EDGE: 'LONG_EDGE',
- SHORT_EDGE: 'SHORT_EDGE'
-};
+ return {
+ DuplexMode: DuplexMode,
+ DuplexType: DuplexType,
+ PolicyEntry: PolicyEntry,
+ PolicySettings: PolicySettings,
+ SerializedSettings: SerializedSettings,
+ Setting: Setting,
+ Settings: Settings,
+ };
+});
cr.define('print_preview.Model', () => {
return {
diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js
index fe78ee05149..ddf522abeb6 100644
--- a/chromium/chrome/browser/resources/print_preview/native_layer.js
+++ b/chromium/chrome/browser/resources/print_preview/native_layer.js
@@ -33,8 +33,8 @@ cr.define('print_preview', function() {
* isInKioskAutoPrintMode: boolean,
* isInAppKioskMode: boolean,
* uiLocale: string,
- * thousandsDelimeter: string,
- * decimalDelimeter: string,
+ * thousandsDelimiter: string,
+ * decimalDelimiter: string,
* unitType: !print_preview.MeasurementSystemUnitType,
* previewModifiable: boolean,
* documentTitle: string,
diff --git a/chromium/chrome/browser/resources/print_preview/polymer3/demo.js b/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
index 6a59ffd92d1..39a1b1bc694 100644
--- a/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
+++ b/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
@@ -2,29 +2,152 @@
// 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-button/paper-button.js';
+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/cr_elements/cr_dialog/cr_dialog.m.js';
+import 'chrome://resources/cr_elements/cr_drawer/cr_drawer.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
+import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
+import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
+import 'chrome://resources/cr_elements/cr_search_field/cr_search_field.m.js';
+import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.m.js';
+import 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js';
+import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/md_select_css.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
class HelloPolymer3Element extends PolymerElement {
static get template() {
return html`
- <div>Hello Polymer3 [[time]]</div>
- <paper-button on-click="onClick_">Update time</paper-button>
+ <style include="md-select">
+ cr-toggle {
+ display: inline-block;
+ }
+ </style>
+
+ <cr-checkbox checked="{{checkboxChecked_}}">
+ [[checkboxChecked_]]
+ </cr-checkbox>
+
+ <div>
+ <cr-toggle checked="{{toggleChecked_}}"></cr-toggle>
+ <span>[[toggleChecked_]]</span>
+ </div>
+
+ <select class="md-select">
+ <option>JS</option>
+ <option>modules</option>
+ <option>are</option>
+ <option>cool</option>
+ </select>
+
+ <cr-input></cr-input>
+
+ <cr-icon-button iron-icon="cr:more-vert"></cr-icon-button>
+
+ <div>
+ <cr-button on-click="onClick_">Show toast</cr-button>
+ <cr-toast><span>I am toasted</span></cr-toast>
+ </div>
+
+ <iron-icon icon="cr:error"></iron-icon>
+
+ <div>
+ <cr-radio-group id="radioGroup" selected="cr">
+ <cr-radio-button name="cr">cr</cr-radio-button>
+ <cr-radio-button name="radio">radio</cr-radio-button>
+ <cr-radio-button name="buttons">buttons</cr-radio-button>
+ </cr-radio-group>
+ </div>
+
+ <div>
+ <cr-button on-click="showDrawer_">Show drawer</cr-button>
+ <cr-drawer heading="Drawer">
+ <div class="drawer-content">Content of drawer</div>
+ </cr-drawer>
+ </div>
+
+ <div>
+ <cr-tabs selected="{{selectedSubpage_}}" tab-names="[[tabNames_]]">
+ </cr-tabs>
+ <div>
+ <template is="dom-if" if="[[isTabASelected_(selectedSubpage_)]]">
+ <span>This is Tab A</span>
+ </template>
+ <template is="dom-if" if="[[isTabBSelected_(selectedSubpage_)]]">
+ <span>This is Tab B</span>
+ </template>
+ </div>
+ </div>
+
+ <div>
+ <cr-button on-click="showDialog_">Click to open dialog</cr-button>
+ <cr-dialog id="dialog">
+ <div slot="title">I am a dialog</div>
+ </cr-dialog>
+ </div>
+
+ <div>
+ <cr-search-field label="test search field"></cr-search-field>
+ <div>
`;
}
static get properties() {
return {
- time: {
+ /** @private */
+ toggleChecked_: Boolean,
+
+ /** @private */
+ checkboxChecked_: Boolean,
+
+ /** @private */
+ selectedSubpage_: {
type: Number,
- value: Date.now(),
+ value: 0,
+ },
+
+ /** @private {Array<string>} */
+ tabNames_: {
+ type: Array,
+ value: () => (['A', 'B']),
},
};
}
+ /** @private */
onClick_() {
- this.time = Date.now();
+ this.shadowRoot.querySelector('cr-toast').show(2000);
+ }
+
+ /** @private */
+ showDrawer_() {
+ this.shadowRoot.querySelector('cr-drawer').openDrawer();
+ }
+
+ /** @private */
+ showDialog_() {
+ this.shadowRoot.querySelector('cr-dialog').showModal();
+ }
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ isTabASelected_() {
+ return this.selectedSubpage_ === 0;
+ }
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ isTabBSelected_() {
+ return this.selectedSubpage_ === 1;
}
} // class HelloPolymer3
diff --git a/chromium/chrome/browser/resources/print_preview/ui/app.js b/chromium/chrome/browser/resources/print_preview/ui/app.js
index afdf54feb0f..8f30d4e6358 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/app.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/app.js
@@ -272,7 +272,7 @@ Polymer({
this.$.model.setPolicySettings(
settings.headerFooter, settings.isHeaderFooterManaged);
this.measurementSystem_ = new print_preview.MeasurementSystem(
- settings.thousandsDelimeter, settings.decimalDelimeter,
+ settings.thousandsDelimiter, settings.decimalDelimiter,
settings.unitType);
this.setSetting('selectionOnly', settings.shouldPrintSelectionOnly);
this.$.sidebar.init(
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 7e5266744e8..390fad8bc1e 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js
@@ -2,496 +2,501 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/** @enum {number} */
-print_preview.DestinationState = {
- INIT: 0,
- SELECTED: 1,
- SET: 2,
- UPDATED: 3,
- ERROR: 4,
-};
-
-(function() {
-'use strict';
-
-/** @type {number} Number of recent destinations to save. */
-const NUM_PERSISTED_DESTINATIONS = 3;
-
-Polymer({
- is: 'print-preview-destination-settings',
-
- behaviors: [
- I18nBehavior,
- SettingsBehavior,
- WebUIListenerBehavior,
- ],
-
- properties: {
- appKioskMode: Boolean,
-
- /** @type {cloudprint.CloudPrintInterface} */
- cloudPrintInterface: {
- type: Object,
- observer: 'onCloudPrintInterfaceSet_',
- },
+cr.define('print_preview', function() {
+ 'use strict';
+
+ /** @enum {number} */
+ const DestinationState = {
+ INIT: 0,
+ SELECTED: 1,
+ SET: 2,
+ UPDATED: 3,
+ ERROR: 4,
+ };
+
+ /** @type {number} Number of recent destinations to save. */
+ const NUM_PERSISTED_DESTINATIONS = 3;
+
+ Polymer({
+ is: 'print-preview-destination-settings',
+
+ behaviors: [
+ I18nBehavior,
+ SettingsBehavior,
+ WebUIListenerBehavior,
+ ],
+
+ properties: {
+ appKioskMode: Boolean,
+
+ /** @type {cloudprint.CloudPrintInterface} */
+ cloudPrintInterface: {
+ type: Object,
+ observer: 'onCloudPrintInterfaceSet_',
+ },
+
+ dark: Boolean,
+
+ /** @type {?print_preview.Destination} */
+ destination: {
+ type: Object,
+ notify: true,
+ value: null,
+ },
+
+ /** @private {!print_preview.DestinationState} */
+ destinationState: {
+ type: Number,
+ notify: true,
+ value: DestinationState.INIT,
+ observer: 'updateDestinationSelect_',
+ },
+
+ disabled: Boolean,
+
+ /** @type {!print_preview.Error} */
+ error: {
+ type: Number,
+ notify: true,
+ observer: 'onErrorChanged_',
+ },
+
+ firstLoad: Boolean,
+
+ /** @type {!print_preview.State} */
+ state: Number,
+
+ /** @private {string} */
+ activeUser_: {
+ type: String,
+ observer: 'onActiveUserChanged_',
+ },
+
+ /** @private {boolean} */
+ cloudPrintDisabled_: Boolean,
+
+ /** @private {?print_preview.DestinationStore} */
+ destinationStore_: {
+ type: Object,
+ value: null,
+ },
+
+ /** @private {!Array<!print_preview.RecentDestination>} */
+ displayedDestinations_: Array,
- dark: Boolean,
+ // <if expr="chromeos">
+ hasPinSetting_: {
+ type: Boolean,
+ computed: 'computeHasPinSetting_(settings.pin.available)',
+ reflectToAttribute: true,
+ },
+ // </if>
- /** @type {?print_preview.Destination} */
- destination: {
- type: Object,
- notify: true,
- value: null,
+ /** @private {?print_preview.InvitationStore} */
+ invitationStore_: {
+ type: Object,
+ value: null,
+ },
+
+ /** @private {boolean} */
+ isDialogOpen_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /** @private {boolean} */
+ noDestinations_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /** @private */
+ shouldHideSpinner_: {
+ type: Boolean,
+ computed: 'computeShouldHideSpinner_(destinationState, destination)',
+ },
+
+ /** @private {string} */
+ statusText_: {
+ type: String,
+ computed: 'computeStatusText_(destination)',
+ },
+
+ /** @private {!Array<string>} */
+ users_: Array,
},
- /** @private {!print_preview.DestinationState} */
- destinationState: {
- type: Number,
- notify: true,
- value: print_preview.DestinationState.INIT,
- observer: 'updateDestinationSelect_',
+ /** @private {string} */
+ lastUser_: '',
+
+ /** @private {!EventTracker} */
+ tracker_: new EventTracker(),
+
+ /** @override */
+ attached: function() {
+ this.destinationStore_ =
+ new print_preview.DestinationStore(this.addWebUIListener.bind(this));
+ this.invitationStore_ = new print_preview.InvitationStore();
+ this.tracker_.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+ this.onDestinationSelect_.bind(this));
+ this.tracker_.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType
+ .SELECTED_DESTINATION_CAPABILITIES_READY,
+ this.onDestinationCapabilitiesReady_.bind(this));
+ this.tracker_.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType.ERROR,
+ this.onDestinationError_.bind(this));
+ // Need to update the recent list when the destination store inserts
+ // destinations, in case any recent destinations have been added to the
+ // store. At startup, recent destinations can be in the sticky settings,
+ // but they should not be displayed in the dropdown until they have been
+ // fetched by the DestinationStore, to ensure that they still exist.
+ this.tracker_.add(
+ assert(this.destinationStore_),
+ print_preview.DestinationStore.EventType.DESTINATIONS_INSERTED,
+ this.updateDropdownDestinations_.bind(this));
},
- disabled: Boolean,
+ /** @override */
+ detached: function() {
+ this.invitationStore_.resetTracker();
+ this.destinationStore_.resetTracker();
+ this.tracker_.removeAll();
+ },
- /** @type {!print_preview.Error} */
- error: {
- type: Number,
- notify: true,
- observer: 'onErrorChanged_',
+ /** @private */
+ onCloudPrintInterfaceSet_: function() {
+ const cloudPrintInterface = assert(this.cloudPrintInterface);
+ this.destinationStore_.setCloudPrintInterface(cloudPrintInterface);
+ this.invitationStore_.setCloudPrintInterface(cloudPrintInterface);
},
- firstLoad: Boolean,
+ /** @private */
+ onActiveUserChanged_: function() {
+ // Re-filter the dropdown destinations for the new account.
+ if (!this.isDialogOpen_) {
+ // Don't update the destination settings UI while the dialog is open in
+ // front of it.
+ this.updateDropdownDestinations_();
+ }
- /** @type {!print_preview.State} */
- state: Number,
+ if (!this.destination ||
+ this.destination.origin !== print_preview.DestinationOrigin.COOKIES) {
+ // Active user changing doesn't impact non-cookie based destinations.
+ return;
+ }
- /** @private {string} */
- activeUser_: {
- type: String,
- observer: 'onActiveUserChanged_',
- },
+ if (this.destination.account === this.activeUser_) {
+ // If the current destination belongs to the new account and the dialog
+ // was waiting for sign in, update the state.
+ if (this.destinationState === DestinationState.SELECTED) {
+ this.destinationState = this.destination.capabilities ?
+ DestinationState.UPDATED :
+ DestinationState.SET;
+ }
+ return;
+ }
- /** @private {boolean} */
- cloudPrintDisabled_: Boolean,
+ if (this.isDialogOpen_) {
+ // Do not update the selected destination if the dialog is open, as this
+ // will change the destination settings UI behind the dialog, and the
+ // user may be selecting a new destination in the dialog anyway. Wait
+ // for the user to select a destination or cancel.
+ return;
+ }
- /** @private {?print_preview.DestinationStore} */
- destinationStore_: {
- type: Object,
- value: null,
+ // Destination belongs to a different account. Reset the destination to
+ // the most recent destination associated with the new account, or the
+ // default.
+ const recent = this.displayedDestinations_.find(d => {
+ return d.origin !== print_preview.DestinationOrigin.COOKIES ||
+ d.account === this.activeUser_;
+ });
+ if (recent) {
+ const success = this.destinationStore_.selectRecentDestinationByKey(
+ print_preview.createRecentDestinationKey(recent),
+ this.displayedDestinations_);
+ if (success) {
+ return;
+ }
+ }
+ this.destinationStore_.selectDefaultDestination();
},
- // <if expr="chromeos">
- hasPinSetting_: {
- type: Boolean,
- computed: 'computeHasPinSetting_(settings.pin.available)',
- reflectToAttribute: true,
+ /**
+ * @param {string} defaultPrinter The system default printer ID.
+ * @param {string} serializedDefaultDestinationRulesStr String with rules
+ * for selecting a default destination.
+ * @param {?Array<string>} userAccounts The signed in user accounts.
+ * @param {boolean} syncAvailable Whether sync is available. Used to
+ * determine whether to wait for user info updates from the handler, or
+ * to always send requests to the Google Cloud Print server.
+ */
+ init: function(
+ defaultPrinter, serializedDefaultDestinationRulesStr, userAccounts,
+ syncAvailable) {
+ this.$.userManager.initUserAccounts(userAccounts, syncAvailable);
+ this.destinationStore_.init(
+ this.appKioskMode, defaultPrinter,
+ serializedDefaultDestinationRulesStr,
+ /** @type {!Array<print_preview.RecentDestination>} */
+ (this.getSettingValue('recentDestinations')));
},
- // </if>
- /** @private {?print_preview.InvitationStore} */
- invitationStore_: {
- type: Object,
- value: null,
- },
+ /** @private */
+ onDestinationSelect_: function() {
+ // If the user selected a destination in the dialog after changing the
+ // active user, do the UI updates that were previously deferred.
+ if (this.isDialogOpen_ && this.lastUser_ !== this.activeUser_) {
+ this.updateDropdownDestinations_();
+ }
- /** @private {boolean} */
- isDialogOpen_: {
- type: Boolean,
- value: false,
+ if (this.state === print_preview.State.FATAL_ERROR) {
+ // Don't let anything reset if there is a fatal error.
+ return;
+ }
+
+ const destination = this.destinationStore_.selectedDestination;
+ if (!!this.activeUser_ ||
+ destination.origin !== print_preview.DestinationOrigin.COOKIES) {
+ this.destinationState = DestinationState.SET;
+ } else {
+ this.destinationState = DestinationState.SELECTED;
+ }
+ // Notify observers that the destination is set only after updating the
+ // destinationState.
+ this.destination = destination;
+ this.updateRecentDestinations_();
},
- /** @private {boolean} */
- noDestinations_: {
- type: Boolean,
- value: false,
+ /** @private */
+ onDestinationCapabilitiesReady_: function() {
+ this.notifyPath('destination.capabilities');
+ this.updateRecentDestinations_();
+ if (this.destinationState === DestinationState.SET) {
+ this.destinationState = DestinationState.UPDATED;
+ }
},
- /** @private {!Array<!print_preview.RecentDestination>} */
- displayedDestinations_: Array,
+ /**
+ * @param {!CustomEvent<!print_preview.DestinationErrorType>} e
+ * @private
+ */
+ onDestinationError_: function(e) {
+ let errorType = print_preview.Error.NONE;
+ switch (e.detail) {
+ case print_preview.DestinationErrorType.INVALID:
+ errorType = print_preview.Error.INVALID_PRINTER;
+ break;
+ case print_preview.DestinationErrorType.UNSUPPORTED:
+ errorType = print_preview.Error.UNSUPPORTED_PRINTER;
+ break;
+ // <if expr="chromeos">
+ case print_preview.DestinationErrorType.NO_DESTINATIONS:
+ errorType = print_preview.Error.NO_DESTINATIONS;
+ this.noDestinations_ = true;
+ break;
+ // </if>
+ default:
+ break;
+ }
+ this.error = errorType;
+ },
/** @private */
- shouldHideSpinner_: {
- type: Boolean,
- computed: 'computeShouldHideSpinner_(destinationState, destination)',
+ onErrorChanged_: function() {
+ if (this.error == print_preview.Error.INVALID_PRINTER ||
+ this.error == print_preview.Error.UNSUPPORTED_PRINTER ||
+ this.error == print_preview.Error.NO_DESTINATIONS) {
+ this.destinationState = DestinationState.ERROR;
+ }
},
- /** @private {string} */
- statusText_: {
- type: String,
- computed: 'computeStatusText_(destination)',
+ /**
+ * @param {!print_preview.RecentDestination} destination
+ * @return {boolean} Whether the destination is Save as PDF or Save to
+ * Drive.
+ */
+ destinationIsDriveOrPdf_: function(destination) {
+ return destination.id ===
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ||
+ destination.id === print_preview.Destination.GooglePromotedId.DOCS;
},
- /** @private {!Array<string>} */
- users_: Array,
- },
-
- /** @private {string} */
- lastUser_: '',
-
- /** @private {!EventTracker} */
- tracker_: new EventTracker(),
-
- /** @override */
- attached: function() {
- this.destinationStore_ =
- new print_preview.DestinationStore(this.addWebUIListener.bind(this));
- this.invitationStore_ = new print_preview.InvitationStore();
- this.tracker_.add(
- this.destinationStore_,
- print_preview.DestinationStore.EventType.DESTINATION_SELECT,
- this.onDestinationSelect_.bind(this));
- this.tracker_.add(
- this.destinationStore_,
- print_preview.DestinationStore.EventType
- .SELECTED_DESTINATION_CAPABILITIES_READY,
- this.onDestinationCapabilitiesReady_.bind(this));
- this.tracker_.add(
- this.destinationStore_, print_preview.DestinationStore.EventType.ERROR,
- this.onDestinationError_.bind(this));
- // Need to update the recent list when the destination store inserts
- // destinations, in case any recent destinations have been added to the
- // store. At startup, recent destinations can be in the sticky settings,
- // but they should not be displayed in the dropdown until they have been
- // fetched by the DestinationStore, to ensure that they still exist.
- this.tracker_.add(
- assert(this.destinationStore_),
- print_preview.DestinationStore.EventType.DESTINATIONS_INSERTED,
- this.updateDropdownDestinations_.bind(this));
- },
-
- /** @override */
- detached: function() {
- this.invitationStore_.resetTracker();
- this.destinationStore_.resetTracker();
- this.tracker_.removeAll();
- },
-
- /** @private */
- onCloudPrintInterfaceSet_: function() {
- const cloudPrintInterface = assert(this.cloudPrintInterface);
- this.destinationStore_.setCloudPrintInterface(cloudPrintInterface);
- this.invitationStore_.setCloudPrintInterface(cloudPrintInterface);
- },
-
- /** @private */
- onActiveUserChanged_: function() {
- // Re-filter the dropdown destinations for the new account.
- if (!this.isDialogOpen_) {
- // Don't update the destination settings UI while the dialog is open in
- // front of it.
- this.updateDropdownDestinations_();
- }
-
- if (!this.destination ||
- this.destination.origin !== print_preview.DestinationOrigin.COOKIES) {
- // Active user changing doesn't impact non-cookie based destinations.
- return;
- }
-
- if (this.destination.account === this.activeUser_) {
- // If the current destination belongs to the new account and the dialog
- // was waiting for sign in, update the state.
- if (this.destinationState === print_preview.DestinationState.SELECTED) {
- this.destinationState = this.destination.capabilities ?
- print_preview.DestinationState.UPDATED :
- print_preview.DestinationState.SET;
+ /** @private */
+ updateRecentDestinations_: function() {
+ if (!this.destination) {
+ return;
}
- return;
- }
-
- if (this.isDialogOpen_) {
- // Do not update the selected destination if the dialog is open, as this
- // will change the destination settings UI behind the dialog, and the user
- // may be selecting a new destination in the dialog anyway. Wait for the
- // user to select a destination or cancel.
- return;
- }
-
- // Destination belongs to a different account. Reset the destination to the
- // most recent destination associated with the new account, or the default.
- const recent = this.displayedDestinations_.find(d => {
- return d.origin !== print_preview.DestinationOrigin.COOKIES ||
- d.account === this.activeUser_;
- });
- if (recent) {
- const success = this.destinationStore_.selectRecentDestinationByKey(
- print_preview.createRecentDestinationKey(recent),
- this.displayedDestinations_);
- if (success) {
+
+ // Determine if this destination is already in the recent destinations,
+ // and where in the array it is located.
+ const newDestination =
+ print_preview.makeRecentDestination(assert(this.destination));
+ const recentDestinations =
+ /** @type {!Array<!print_preview.RecentDestination>} */ (
+ this.getSettingValue('recentDestinations'));
+ let indexFound = recentDestinations.findIndex(function(recent) {
+ return (
+ newDestination.id == recent.id &&
+ newDestination.origin == recent.origin);
+ });
+
+ // No change
+ if (indexFound == 0 &&
+ recentDestinations[0].capabilities == newDestination.capabilities) {
return;
}
- }
- this.destinationStore_.selectDefaultDestination();
- },
-
- /**
- * @param {string} defaultPrinter The system default printer ID.
- * @param {string} serializedDefaultDestinationRulesStr String with rules for
- * selecting a default destination.
- * @param {?Array<string>} userAccounts The signed in user accounts.
- * @param {boolean} syncAvailable Whether sync is available. Used to determine
- * whether to wait for user info updates from the handler, or to always
- * send requests to the Google Cloud Print server.
- */
- init: function(
- defaultPrinter, serializedDefaultDestinationRulesStr, userAccounts,
- syncAvailable) {
- this.$.userManager.initUserAccounts(userAccounts, syncAvailable);
- this.destinationStore_.init(
- this.appKioskMode, defaultPrinter, serializedDefaultDestinationRulesStr,
- /** @type {!Array<print_preview.RecentDestination>} */
- (this.getSettingValue('recentDestinations')));
- },
-
- /** @private */
- onDestinationSelect_: function() {
- // If the user selected a destination in the dialog after changing the
- // active user, do the UI updates that were previously deferred.
- if (this.isDialogOpen_ && this.lastUser_ !== this.activeUser_) {
- this.updateDropdownDestinations_();
- }
-
- if (this.state === print_preview.State.FATAL_ERROR) {
- // Don't let anything reset if there is a fatal error.
- return;
- }
-
- const destination = this.destinationStore_.selectedDestination;
- if (!!this.activeUser_ ||
- destination.origin !== print_preview.DestinationOrigin.COOKIES) {
- this.destinationState = print_preview.DestinationState.SET;
- } else {
- this.destinationState = print_preview.DestinationState.SELECTED;
- }
- // Notify observers that the destination is set only after updating the
- // destinationState.
- this.destination = destination;
- this.updateRecentDestinations_();
- },
-
- /** @private */
- onDestinationCapabilitiesReady_: function() {
- this.notifyPath('destination.capabilities');
- this.updateRecentDestinations_();
- if (this.destinationState === print_preview.DestinationState.SET) {
- this.destinationState = print_preview.DestinationState.UPDATED;
- }
- },
-
- /**
- * @param {!CustomEvent<!print_preview.DestinationErrorType>} e
- * @private
- */
- onDestinationError_: function(e) {
- let errorType = print_preview.Error.NONE;
- switch (e.detail) {
- case print_preview.DestinationErrorType.INVALID:
- errorType = print_preview.Error.INVALID_PRINTER;
- break;
- case print_preview.DestinationErrorType.UNSUPPORTED:
- errorType = print_preview.Error.UNSUPPORTED_PRINTER;
- break;
- // <if expr="chromeos">
- case print_preview.DestinationErrorType.NO_DESTINATIONS:
- errorType = print_preview.Error.NO_DESTINATIONS;
- this.noDestinations_ = true;
- break;
- // </if>
- default:
- break;
- }
- this.error = errorType;
- },
-
- /** @private */
- onErrorChanged_: function() {
- if (this.error == print_preview.Error.INVALID_PRINTER ||
- this.error == print_preview.Error.UNSUPPORTED_PRINTER ||
- this.error == print_preview.Error.NO_DESTINATIONS) {
- this.destinationState = print_preview.DestinationState.ERROR;
- }
- },
-
- /**
- * @param {!print_preview.RecentDestination} destination
- * @return {boolean} Whether the destination is Save as PDF or Save to Drive.
- */
- destinationIsDriveOrPdf_: function(destination) {
- return destination.id ===
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ||
- destination.id === print_preview.Destination.GooglePromotedId.DOCS;
- },
-
- /** @private */
- updateRecentDestinations_: function() {
- if (!this.destination) {
- return;
- }
-
- // Determine if this destination is already in the recent destinations,
- // and where in the array it is located.
- const newDestination =
- print_preview.makeRecentDestination(assert(this.destination));
- const recentDestinations =
- /** @type {!Array<!print_preview.RecentDestination>} */ (
- this.getSettingValue('recentDestinations'));
- let indexFound = recentDestinations.findIndex(function(recent) {
- return (
- newDestination.id == recent.id &&
- newDestination.origin == recent.origin);
- });
-
- // No change
- if (indexFound == 0 &&
- recentDestinations[0].capabilities == newDestination.capabilities) {
- return;
- }
- const isNew = indexFound == -1;
-
- // Shift the array so that the nth most recent destination is located at
- // index n.
- if (isNew && recentDestinations.length == NUM_PERSISTED_DESTINATIONS) {
- indexFound = NUM_PERSISTED_DESTINATIONS - 1;
- }
- if (indexFound != -1) {
- this.setSettingSplice('recentDestinations', indexFound, 1, null);
- }
-
- // Add the most recent destination
- this.setSettingSplice('recentDestinations', 0, 0, newDestination);
- if (!this.destinationIsDriveOrPdf_(newDestination) && isNew) {
- this.updateDropdownDestinations_();
- }
- },
-
- /** @private */
- updateDropdownDestinations_: function() {
- this.displayedDestinations_ =
- /** @type {!Array<!print_preview.RecentDestination>} */ (
- this.getSettingValue('recentDestinations'))
- .filter(d => {
- return !this.destinationIsDriveOrPdf_(d) &&
- (d.origin !== print_preview.DestinationOrigin.COOKIES ||
- d.account === this.activeUser_);
- });
- },
-
- /**
- * @return {boolean} Whether the destinations dropdown should be disabled.
- * @private
- */
- shouldDisableDropdown_: function() {
- return this.state === print_preview.State.FATAL_ERROR ||
- (this.destinationState === print_preview.DestinationState.UPDATED &&
- this.disabled && this.state !== print_preview.State.NOT_READY);
- },
-
- /** @private */
- computeShouldHideSpinner_: function() {
- return this.destinationState === print_preview.DestinationState.ERROR ||
- this.destinationState === print_preview.DestinationState.UPDATED ||
- (this.destinationState === print_preview.DestinationState.SET &&
- !!this.destination &&
- (!!this.destination.capabilities ||
- this.destination.id ===
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF));
- },
-
- /**
- * @return {string} The connection status text to display.
- * @private
- */
- computeStatusText_: function() {
- // |destination| can be either undefined, or null here.
- if (!this.destination) {
- return '';
- }
-
- return this.destination.shouldShowInvalidCertificateError ?
- this.i18n('noLongerSupportedFragment') :
- this.destination.connectionStatusText;
- },
-
- // <if expr="chromeos">
- /**
- * @return {boolean}
- * @private
- */
- computeHasPinSetting_: function() {
- return this.getSetting('pin').available;
- },
- // </if>
-
- /**
- * @param {!CustomEvent<string>} e Event containing the key of the recent
- * destination that was selected, or "seeMore".
- * @private
- */
- onSelectedDestinationOptionChange_: function(e) {
- const value = e.detail;
- if (value === 'seeMore') {
- this.destinationStore_.startLoadAllDestinations();
- if (this.activeUser_) {
- this.invitationStore_.startLoadingInvitations(this.activeUser_);
+ const isNew = indexFound == -1;
+
+ // Shift the array so that the nth most recent destination is located at
+ // index n.
+ if (isNew && recentDestinations.length == NUM_PERSISTED_DESTINATIONS) {
+ indexFound = NUM_PERSISTED_DESTINATIONS - 1;
+ }
+ if (indexFound != -1) {
+ this.setSettingSplice('recentDestinations', indexFound, 1, null);
}
- this.$.destinationDialog.get().show();
- this.lastUser_ = this.activeUser_;
- this.isDialogOpen_ = true;
- } else {
- const success = this.destinationStore_.selectRecentDestinationByKey(
- value, this.displayedDestinations_);
- if (!success) {
- this.error = print_preview.Error.INVALID_PRINTER;
+
+ // Add the most recent destination
+ this.setSettingSplice('recentDestinations', 0, 0, newDestination);
+ if (!this.destinationIsDriveOrPdf_(newDestination) && isNew) {
+ this.updateDropdownDestinations_();
}
- }
- },
-
- /**
- * @param {!CustomEvent<string>} e Event containing the new active user
- * account.
- * @private
- */
- onAccountChange_: function(e) {
- this.$.userManager.updateActiveUser(e.detail, true);
- },
-
- /** @private */
- onDialogClose_: function() {
- // Reset the select value if the user dismissed the dialog without
- // selecting a new destination.
- if (this.lastUser_ != this.activeUser_) {
- this.updateDropdownDestinations_();
- }
- this.updateDestinationSelect_();
- this.isDialogOpen_ = false;
- },
-
- /** @private */
- updateDestinationSelect_: function() {
+ },
+
+ /** @private */
+ updateDropdownDestinations_: function() {
+ this.displayedDestinations_ =
+ /** @type {!Array<!print_preview.RecentDestination>} */ (
+ this.getSettingValue('recentDestinations'))
+ .filter(d => {
+ return !this.destinationIsDriveOrPdf_(d) &&
+ (d.origin !== print_preview.DestinationOrigin.COOKIES ||
+ d.account === this.activeUser_);
+ });
+ },
+
+ /**
+ * @return {boolean} Whether the destinations dropdown should be disabled.
+ * @private
+ */
+ shouldDisableDropdown_: function() {
+ return this.state === print_preview.State.FATAL_ERROR ||
+ (this.destinationState === DestinationState.UPDATED &&
+ this.disabled && this.state !== print_preview.State.NOT_READY);
+ },
+
+ /** @private */
+ computeShouldHideSpinner_: function() {
+ return this.destinationState === DestinationState.ERROR ||
+ this.destinationState === DestinationState.UPDATED ||
+ (this.destinationState === DestinationState.SET &&
+ !!this.destination &&
+ (!!this.destination.capabilities ||
+ this.destination.id ===
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF));
+ },
+
+ /**
+ * @return {string} The connection status text to display.
+ * @private
+ */
+ computeStatusText_: function() {
+ // |destination| can be either undefined, or null here.
+ if (!this.destination) {
+ return '';
+ }
+
+ return this.destination.shouldShowInvalidCertificateError ?
+ this.i18n('noLongerSupportedFragment') :
+ this.destination.connectionStatusText;
+ },
+
// <if expr="chromeos">
- if (this.destinationState === print_preview.DestinationState.ERROR &&
- !this.destination) {
- return;
- }
+ /**
+ * @return {boolean}
+ * @private
+ */
+ computeHasPinSetting_: function() {
+ return this.getSetting('pin').available;
+ },
// </if>
- if (this.destinationState === print_preview.DestinationState.INIT ||
- this.destinationState === print_preview.DestinationState.SELECTED) {
- return;
- }
-
- const shouldFocus =
- this.destinationState !== print_preview.DestinationState.SET &&
- !this.firstLoad;
- Polymer.RenderStatus.beforeNextRender(this.$.destinationSelect, () => {
- this.$.destinationSelect.updateDestination();
- if (shouldFocus) {
- this.$.destinationSelect.focus();
+ /**
+ * @param {!CustomEvent<string>} e Event containing the key of the recent
+ * destination that was selected, or "seeMore".
+ * @private
+ */
+ onSelectedDestinationOptionChange_: function(e) {
+ const value = e.detail;
+ if (value === 'seeMore') {
+ this.destinationStore_.startLoadAllDestinations();
+ if (this.activeUser_) {
+ this.invitationStore_.startLoadingInvitations(this.activeUser_);
+ }
+ this.$.destinationDialog.get().show();
+ this.lastUser_ = this.activeUser_;
+ this.isDialogOpen_ = true;
+ } else {
+ const success = this.destinationStore_.selectRecentDestinationByKey(
+ value, this.displayedDestinations_);
+ if (!success) {
+ this.error = print_preview.Error.INVALID_PRINTER;
+ }
}
- });
- },
+ },
+
+ /**
+ * @param {!CustomEvent<string>} e Event containing the new active user
+ * account.
+ * @private
+ */
+ onAccountChange_: function(e) {
+ this.$.userManager.updateActiveUser(e.detail, true);
+ },
+
+ /** @private */
+ onDialogClose_: function() {
+ // Reset the select value if the user dismissed the dialog without
+ // selecting a new destination.
+ if (this.lastUser_ != this.activeUser_) {
+ this.updateDropdownDestinations_();
+ }
+ this.updateDestinationSelect_();
+ this.isDialogOpen_ = false;
+ },
+
+ /** @private */
+ updateDestinationSelect_: function() {
+ // <if expr="chromeos">
+ if (this.destinationState === DestinationState.ERROR &&
+ !this.destination) {
+ return;
+ }
+ // </if>
+
+ if (this.destinationState === DestinationState.INIT ||
+ this.destinationState === DestinationState.SELECTED) {
+ return;
+ }
+
+ const shouldFocus =
+ this.destinationState !== DestinationState.SET && !this.firstLoad;
+ Polymer.RenderStatus.beforeNextRender(this.$.destinationSelect, () => {
+ this.$.destinationSelect.updateDestination();
+ if (shouldFocus) {
+ this.$.destinationSelect.focus();
+ }
+ });
+ },
+ });
+
+ return {
+ DestinationState: DestinationState,
+ };
});
-})();
diff --git a/chromium/chrome/browser/resources/print_preview/ui/highlight_utils.js b/chromium/chrome/browser/resources/print_preview/ui/highlight_utils.js
index f88c99430ed..07fc9719c2e 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/highlight_utils.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/highlight_utils.js
@@ -2,20 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-/**
- * @typedef {{
- * highlights: !Array<!Node>,
- * bubbles: !Array<!Node>
- * }}
- */
-print_preview.HighlightResults;
cr.define('print_preview', function() {
'use strict';
/**
+ * @typedef {{
+ * highlights: !Array<!Node>,
+ * bubbles: !Array<!Node>
+ * }}
+ */
+ let HighlightResults;
+
+ /**
* @param {!HTMLElement} element The element to update. Element should have a
* shadow root.
* @param {?RegExp} query The current search query
@@ -65,6 +65,7 @@ cr.define('print_preview', function() {
}
return {
+ HighlightResults: HighlightResults,
updateHighlights: updateHighlights,
};
});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/margin_control.html b/chromium/chrome/browser/resources/print_preview/ui/margin_control.html
index 4aa2d7e9dc9..2d21005cf9e 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margin_control.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/margin_control.html
@@ -70,7 +70,6 @@
overflow: hidden;
padding: 1px;
position: absolute;
- width: 60px;
}
@media (prefers-color-scheme: light) {
@@ -136,6 +135,7 @@
#input {
padding-inline-end: 0;
text-align: end;
+ width: 44px;
}
#unit {
diff --git a/chromium/chrome/browser/resources/print_preview/ui/margin_control.js b/chromium/chrome/browser/resources/print_preview/ui/margin_control.js
index d3ccb88904f..0e9dca3478f 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margin_control.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/margin_control.js
@@ -180,22 +180,22 @@ Polymer({
* @private
*/
parseValueToPts_: function(value) {
- // Removing whitespace anywhere in the string.
- value = value.replace(/\s*/g, '');
+ value = value.trim();
if (value.length == 0) {
return null;
}
assert(this.measurementSystem);
- const decimal = this.measurementSystem.decimalDelimeter;
- const thousands = this.measurementSystem.thousandsDelimeter;
- const validationRegex = new RegExp(
- `^(^-?)(((\\d)(\\${thousands}\\d{3})*)(\\${decimal}\\d*)?|` +
- `((\\d)?(\\${thousands}\\d{3})*)(\\${decimal}\\d*))`);
+ const decimal = this.measurementSystem.decimalDelimiter;
+ const thousands = this.measurementSystem.thousandsDelimiter;
+ const whole = `(?:0|[1-9]\\d*|[1-9]\\d{0,2}(?:[${thousands}]\\d{3})*)`;
+ const fractional = `(?:[${decimal}]\\d*)`;
+ const validationRegex =
+ new RegExp(`^-?(?:${whole}${fractional}?|${fractional})$`);
if (validationRegex.test(value)) {
- // Replacing decimal point with the dot symbol in order to use
- // parseFloat() properly.
- value = value.replace(new RegExp(`\\${decimal}{1}`), '.');
- value = value.replace(new RegExp(`\\${thousands}`, 'g'), '');
+ // Removing thousands delimiters and replacing the decimal delimiter with
+ // the dot symbol in order to use parseFloat() properly.
+ value = value.replace(new RegExp(`\\${thousands}`, 'g'), '')
+ .replace(decimal, '.');
return this.measurementSystem.convertToPoints(parseFloat(value));
}
return null;
@@ -211,7 +211,9 @@ Polymer({
assert(this.measurementSystem);
value = this.measurementSystem.convertFromPoints(value);
value = this.measurementSystem.roundValue(value);
- return value.toString();
+ // Convert the dot symbol to the decimal delimiter for the locale.
+ return value.toString().replace(
+ '.', this.measurementSystem.decimalDelimiter);
},
/**
diff --git a/chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js b/chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js
index eb6adf25058..b507fc864bb 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js
@@ -2,538 +2,546 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-
-/**
- * @const {!Map<!print_preview.ticket_items.CustomMarginsOrientation, string>}
- */
-print_preview.MARGIN_KEY_MAP = new Map([
- [print_preview.ticket_items.CustomMarginsOrientation.TOP, 'marginTop'],
- [print_preview.ticket_items.CustomMarginsOrientation.RIGHT, 'marginRight'],
- [print_preview.ticket_items.CustomMarginsOrientation.BOTTOM, 'marginBottom'],
- [print_preview.ticket_items.CustomMarginsOrientation.LEFT, 'marginLeft']
-]);
-
-(function() {
-'use strict';
-
-/** @const {number} */
-const MINIMUM_DISTANCE = 72; // 1 inch
-
-Polymer({
- is: 'print-preview-margin-control-container',
-
- behaviors: [SettingsBehavior],
-
- properties: {
- /** @type {!print_preview.Size} */
- pageSize: {
- type: Object,
- notify: true,
- },
- /** @type {!print_preview.Margins} */
- documentMargins: {
- type: Object,
- notify: true,
+cr.define('print_preview', function() {
+ 'use strict';
+
+ /**
+ * @const {!Map<!print_preview.ticket_items.CustomMarginsOrientation, string>}
+ */
+ const MARGIN_KEY_MAP = new Map([
+ [print_preview.ticket_items.CustomMarginsOrientation.TOP, 'marginTop'],
+ [print_preview.ticket_items.CustomMarginsOrientation.RIGHT, 'marginRight'],
+ [
+ print_preview.ticket_items.CustomMarginsOrientation.BOTTOM, 'marginBottom'
+ ],
+ [print_preview.ticket_items.CustomMarginsOrientation.LEFT, 'marginLeft']
+ ]);
+
+ /** @const {number} */
+ const MINIMUM_DISTANCE = 72; // 1 inch
+
+ Polymer({
+ is: 'print-preview-margin-control-container',
+
+ behaviors: [SettingsBehavior],
+
+ properties: {
+ /** @type {!print_preview.Size} */
+ pageSize: {
+ type: Object,
+ notify: true,
+ },
+
+ /** @type {!print_preview.Margins} */
+ documentMargins: {
+ type: Object,
+ notify: true,
+ },
+
+ previewLoaded: Boolean,
+
+ /** @type {?print_preview.MeasurementSystem} */
+ measurementSystem: Object,
+
+ /** @type {!print_preview.State} */
+ state: {
+ type: Number,
+ observer: 'onStateChanged_',
+ },
+
+ /** @private {number} */
+ scaleTransform_: {
+ type: Number,
+ notify: true,
+ value: 0,
+ },
+
+ /** @private {!print_preview.Coordinate2d} */
+ translateTransform_: {
+ type: Object,
+ notify: true,
+ value: new print_preview.Coordinate2d(0, 0),
+ },
+
+ /** @private {?print_preview.Size} */
+ clipSize_: {
+ type: Object,
+ notify: true,
+ value: null,
+ },
+
+ /** @private {boolean} */
+ available_: {
+ type: Boolean,
+ notify: true,
+ computed: 'computeAvailable_(previewLoaded, settings.margins.value)',
+ observer: 'onAvailableChange_',
+ },
+
+ /** @private {boolean} */
+ invisible_: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: true,
+ },
+
+ /**
+ * @private {!Array<!print_preview.ticket_items.CustomMarginsOrientation>}
+ */
+ marginSides_: {
+ type: Array,
+ notify: true,
+ value: [
+ print_preview.ticket_items.CustomMarginsOrientation.TOP,
+ print_preview.ticket_items.CustomMarginsOrientation.RIGHT,
+ print_preview.ticket_items.CustomMarginsOrientation.BOTTOM,
+ print_preview.ticket_items.CustomMarginsOrientation.LEFT,
+ ],
+ },
+
+ /**
+ * String attribute used to set cursor appearance. Possible values:
+ * empty (''): No margin control is currently being dragged.
+ * 'dragging-horizontal': The left or right control is being dragged.
+ * 'dragging-vertical': The top or bottom control is being dragged.
+ * @private {string}
+ */
+ dragging_: {
+ type: String,
+ reflectToAttribute: true,
+ value: '',
+ },
},
- previewLoaded: Boolean,
+ /** @private {boolean} */
+ textboxFocused_: false,
- /** @type {?print_preview.MeasurementSystem} */
- measurementSystem: Object,
+ observers: [
+ 'onMarginSettingsChange_(settings.customMargins.value)',
+ 'onMediaSizeOrLayoutChange_(' +
+ 'settings.mediaSize.value, settings.layout.value)',
+ ],
- /** @type {!print_preview.State} */
- state: {
- type: Number,
- observer: 'onStateChanged_',
- },
+ /** @private {!print_preview.Coordinate2d} */
+ pointerStartPositionInPixels_: new print_preview.Coordinate2d(0, 0),
+
+ /** @private {?print_preview.Coordinate2d} */
+ marginStartPositionInPixels_: null,
+
+ /** @private {?boolean} */
+ resetMargins_: null,
- /** @private {number} */
- scaleTransform_: {
- type: Number,
- notify: true,
- value: 0,
+ /**
+ * @return {boolean}
+ * @private
+ */
+ computeAvailable_: function() {
+ return this.previewLoaded && !!this.clipSize_ &&
+ this.getSettingValue('margins') ==
+ print_preview.ticket_items.MarginsTypeValue.CUSTOM &&
+ !!this.pageSize;
},
- /** @private {!print_preview.Coordinate2d} */
- translateTransform_: {
- type: Object,
- notify: true,
- value: new print_preview.Coordinate2d(0, 0),
+ /** @private */
+ onAvailableChange_: function() {
+ if (this.available_ && this.resetMargins_) {
+ // Set the custom margins values to the current document margins if the
+ // custom margins were reset.
+ const newMargins = {};
+ for (const side of Object.values(
+ print_preview.ticket_items.CustomMarginsOrientation)) {
+ const key = print_preview.MARGIN_KEY_MAP.get(side);
+ newMargins[key] = this.documentMargins.get(side);
+ }
+ this.setSetting('customMargins', newMargins);
+ this.resetMargins_ = false;
+ }
+ this.invisible_ = !this.available_;
},
- /** @private {?print_preview.Size} */
- clipSize_: {
- type: Object,
- notify: true,
- value: null,
+ /** @private */
+ onMarginSettingsChange_: function() {
+ const margins = this.getSettingValue('customMargins');
+ if (margins.marginTop === undefined) {
+ // This may be called when print preview model initially sets the
+ // settings. It sets custom margins empty by default.
+ return;
+ }
+ this.shadowRoot.querySelectorAll('print-preview-margin-control')
+ .forEach(control => {
+ const key = print_preview.MARGIN_KEY_MAP.get(control.side);
+ const newValue = margins[key] || 0;
+ control.setPositionInPts(newValue);
+ control.setTextboxValue(newValue);
+ });
},
- /** @private {boolean} */
- available_: {
- type: Boolean,
- notify: true,
- computed: 'computeAvailable_(previewLoaded, settings.margins.value)',
- observer: 'onAvailableChange_',
+ /** @private */
+ onMediaSizeOrLayoutChange_: function() {
+ // Reset the custom margins when the paper size changes. Don't do this if
+ // it is the first preview.
+ if (this.resetMargins_ === null) {
+ return;
+ }
+
+ this.resetMargins_ = true;
+ const marginsSetting = this.getSetting('margins');
+ if (marginsSetting.value ==
+ print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ // Set the margins value to default first.
+ this.setSetting(
+ 'margins', print_preview.ticket_items.MarginsTypeValue.DEFAULT);
+ }
+ // Reset custom margins so that the sticky value is not restored for the
+ // new paper size.
+ this.setSetting('customMargins', {});
},
- /** @private {boolean} */
- invisible_: {
- type: Boolean,
- reflectToAttribute: true,
- value: true,
+ /** @private */
+ onStateChanged_: function() {
+ if (this.state == print_preview.State.READY &&
+ this.resetMargins_ === null) {
+ // Don't reset margins if there are sticky values. Otherwise, set them
+ // to the document margins when the user selects custom margins.
+ this.resetMargins_ =
+ this.getSettingValue('customMargins').marginTop === undefined;
+ }
},
/**
- * @private {!Array<!print_preview.ticket_items.CustomMarginsOrientation>}
+ * @return {boolean} Whether the controls should be disabled.
+ * @private
*/
- marginSides_: {
- type: Array,
- notify: true,
- value: [
- print_preview.ticket_items.CustomMarginsOrientation.TOP,
- print_preview.ticket_items.CustomMarginsOrientation.RIGHT,
- print_preview.ticket_items.CustomMarginsOrientation.BOTTOM,
- print_preview.ticket_items.CustomMarginsOrientation.LEFT,
- ],
+ controlsDisabled_: function() {
+ return this.state !== print_preview.State.READY || this.invisible_;
},
/**
- * String attribute used to set cursor appearance. Possible values:
- * empty (''): No margin control is currently being dragged.
- * 'dragging-horizontal': The left or right control is being dragged.
- * 'dragging-vertical': The top or bottom control is being dragged.
- * @private {string}
+ * @param {!print_preview.ticket_items.CustomMarginsOrientation} orientation
+ * Orientation value to test.
+ * @return {boolean} Whether the given orientation is TOP or BOTTOM.
+ * @private
*/
- dragging_: {
- type: String,
- reflectToAttribute: true,
- value: '',
+ isTopOrBottom_: function(orientation) {
+ return orientation ==
+ print_preview.ticket_items.CustomMarginsOrientation.TOP ||
+ orientation ==
+ print_preview.ticket_items.CustomMarginsOrientation.BOTTOM;
},
- },
- /** @private {boolean} */
- textboxFocused_: false,
+ /**
+ * @param {!HTMLElement} control Control being repositioned.
+ * @param {!print_preview.Coordinate2d} posInPixels Desired position, in
+ * pixels.
+ * @return {number} The new position for the control, in pts. Returns the
+ * position for the dimension that the control operates in, i.e.
+ * x direction for the left/right controls, y direction otherwise.
+ * @private
+ */
+ posInPixelsToPts_: function(control, posInPixels) {
+ const side =
+ /** @type {print_preview.ticket_items.CustomMarginsOrientation} */ (
+ control.side);
+ return this.clipAndRoundValue_(
+ side,
+ control.convertPixelsToPts(
+ this.isTopOrBottom_(side) ? posInPixels.y : posInPixels.x));
+ },
- observers: [
- 'onMarginSettingsChange_(settings.customMargins.value)',
- 'onMediaSizeOrLayoutChange_(' +
- 'settings.mediaSize.value, settings.layout.value)',
- ],
+ /**
+ * Moves the position of the given control to the desired position in pts
+ * within some constraint minimum and maximum.
+ * @param {!HTMLElement} control Control to move.
+ * @param {number} posInPts Desired position to move to, in pts. Position is
+ * 1 dimensional and represents position in the x direction if control
+ * is for the left or right margin, and the y direction otherwise.
+ * @private
+ */
+ moveControlWithConstraints_: function(control, posInPts) {
+ control.setPositionInPts(posInPts);
+ control.setTextboxValue(posInPts);
+ },
- /** @private {!print_preview.Coordinate2d} */
- pointerStartPositionInPixels_: new print_preview.Coordinate2d(0, 0),
+ /**
+ * Translates the position of the margin control relative to the pointer
+ * position in pixels.
+ * @param {!print_preview.Coordinate2d} pointerPosition New position of
+ * the pointer.
+ * @return {!print_preview.Coordinate2d} New position of the margin control.
+ */
+ translatePointerToPositionInPixels: function(pointerPosition) {
+ return new print_preview.Coordinate2d(
+ pointerPosition.x - this.pointerStartPositionInPixels_.x +
+ this.marginStartPositionInPixels_.x,
+ pointerPosition.y - this.pointerStartPositionInPixels_.y +
+ this.marginStartPositionInPixels_.y);
+ },
- /** @private {?print_preview.Coordinate2d} */
- marginStartPositionInPixels_: null,
+ /**
+ * Called when the pointer moves in the custom margins component. Moves the
+ * dragged margin control.
+ * @param {!PointerEvent} event Contains the position of the pointer.
+ * @private
+ */
+ onPointerMove_: function(event) {
+ const control =
+ /** @type {!PrintPreviewMarginControlElement} */ (event.target);
+ const posInPts = this.posInPixelsToPts_(
+ control,
+ this.translatePointerToPositionInPixels(
+ new print_preview.Coordinate2d(event.x, event.y)));
+ this.moveControlWithConstraints_(control, posInPts);
+ },
- /** @private {?boolean} */
- resetMargins_: null,
+ /**
+ * Called when the pointer is released in the custom margins component.
+ * Releases the dragged margin control.
+ * @param {!PointerEvent} event Contains the position of the pointer.
+ * @private
+ */
+ onPointerUp_: function(event) {
+ const control =
+ /** @type {!PrintPreviewMarginControlElement} */ (event.target);
+ this.dragging_ = '';
+ const posInPixels = this.translatePointerToPositionInPixels(
+ new print_preview.Coordinate2d(event.x, event.y));
+ const posInPts = this.posInPixelsToPts_(control, posInPixels);
+ this.moveControlWithConstraints_(control, posInPts);
+ this.setMargin_(control.side, posInPts);
+ this.updateClippingMask(this.clipSize_);
+ this.unlisten(control, 'pointercancel', 'onPointerUp_');
+ this.unlisten(control, 'pointerup', 'onPointerUp_');
+ this.unlisten(control, 'pointermove', 'onPointerMove_');
+
+ this.fire('margin-drag-changed', false);
+ },
- /**
- * @return {boolean}
- * @private
- */
- computeAvailable_: function() {
- return this.previewLoaded && !!this.clipSize_ &&
- this.getSettingValue('margins') ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM &&
- !!this.pageSize;
- },
-
- /** @private */
- onAvailableChange_: function() {
- if (this.available_ && this.resetMargins_) {
- // Set the custom margins values to the current document margins if the
- // custom margins were reset.
- const newMargins = {};
- for (const side of Object.values(
- print_preview.ticket_items.CustomMarginsOrientation)) {
- const key = print_preview.MARGIN_KEY_MAP.get(side);
- newMargins[key] = this.documentMargins.get(side);
+ /**
+ * @param {boolean} invisible Whether the margin controls should be
+ * invisible.
+ */
+ setInvisible: function(invisible) {
+ // Ignore changes if the margin controls are not available.
+ if (!this.available_) {
+ return;
}
- this.setSetting('customMargins', newMargins);
- this.resetMargins_ = false;
- }
- this.invisible_ = !this.available_;
- },
-
- /** @private */
- onMarginSettingsChange_: function() {
- const margins = this.getSettingValue('customMargins');
- if (margins.marginTop === undefined) {
- // This may be called when print preview model initially sets the
- // settings. It sets custom margins empty by default.
- return;
- }
- this.shadowRoot.querySelectorAll('print-preview-margin-control')
- .forEach(control => {
- const key = print_preview.MARGIN_KEY_MAP.get(control.side);
- const newValue = margins[key] || 0;
- control.setPositionInPts(newValue);
- control.setTextboxValue(newValue);
- });
- },
-
- /** @private */
- onMediaSizeOrLayoutChange_: function() {
- // Reset the custom margins when the paper size changes. Don't do this if it
- // is the first preview.
- if (this.resetMargins_ === null) {
- return;
- }
-
- this.resetMargins_ = true;
- const marginsSetting = this.getSetting('margins');
- if (marginsSetting.value ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
- // Set the margins value to default first.
- this.setSetting(
- 'margins', print_preview.ticket_items.MarginsTypeValue.DEFAULT);
- }
- // Reset custom margins so that the sticky value is not restored for the new
- // paper size.
- this.setSetting('customMargins', {});
- },
-
- /** @private */
- onStateChanged_: function() {
- if (this.state == print_preview.State.READY &&
- this.resetMargins_ === null) {
- // Don't reset margins if there are sticky values. Otherwise, set them to
- // the document margins when the user selects custom margins.
- this.resetMargins_ =
- this.getSettingValue('customMargins').marginTop === undefined;
- }
- },
-
- /**
- * @return {boolean} Whether the controls should be disabled.
- * @private
- */
- controlsDisabled_: function() {
- return this.state !== print_preview.State.READY || this.invisible_;
- },
-
- /**
- * @param {!print_preview.ticket_items.CustomMarginsOrientation} orientation
- * Orientation value to test.
- * @return {boolean} Whether the given orientation is TOP or BOTTOM.
- * @private
- */
- isTopOrBottom_: function(orientation) {
- return orientation ==
- print_preview.ticket_items.CustomMarginsOrientation.TOP ||
- orientation ==
- print_preview.ticket_items.CustomMarginsOrientation.BOTTOM;
- },
-
- /**
- * @param {!HTMLElement} control Control being repositioned.
- * @param {!print_preview.Coordinate2d} posInPixels Desired position, in
- * pixels.
- * @return {number} The new position for the control, in pts. Returns the
- * position for the dimension that the control operates in, i.e.
- * x direction for the left/right controls, y direction otherwise.
- * @private
- */
- posInPixelsToPts_: function(control, posInPixels) {
- const side =
- /** @type {print_preview.ticket_items.CustomMarginsOrientation} */ (
- control.side);
- return this.clipAndRoundValue_(
- side,
- control.convertPixelsToPts(
- this.isTopOrBottom_(side) ? posInPixels.y : posInPixels.x));
- },
-
- /**
- * Moves the position of the given control to the desired position in pts
- * within some constraint minimum and maximum.
- * @param {!HTMLElement} control Control to move.
- * @param {number} posInPts Desired position to move to, in pts. Position is
- * 1 dimensional and represents position in the x direction if control is
- * for the left or right margin, and the y direction otherwise.
- * @private
- */
- moveControlWithConstraints_: function(control, posInPts) {
- control.setPositionInPts(posInPts);
- control.setTextboxValue(posInPts);
- },
-
- /**
- * Translates the position of the margin control relative to the pointer
- * position in pixels.
- * @param {!print_preview.Coordinate2d} pointerPosition New position of
- * the pointer.
- * @return {!print_preview.Coordinate2d} New position of the margin control.
- */
- translatePointerToPositionInPixels: function(pointerPosition) {
- return new print_preview.Coordinate2d(
- pointerPosition.x - this.pointerStartPositionInPixels_.x +
- this.marginStartPositionInPixels_.x,
- pointerPosition.y - this.pointerStartPositionInPixels_.y +
- this.marginStartPositionInPixels_.y);
- },
- /**
- * Called when the pointer moves in the custom margins component. Moves the
- * dragged margin control.
- * @param {!PointerEvent} event Contains the position of the pointer.
- * @private
- */
- onPointerMove_: function(event) {
- const control =
- /** @type {!PrintPreviewMarginControlElement} */ (event.target);
- const posInPts = this.posInPixelsToPts_(
- control,
- this.translatePointerToPositionInPixels(
- new print_preview.Coordinate2d(event.x, event.y)));
- this.moveControlWithConstraints_(control, posInPts);
- },
-
- /**
- * Called when the pointer is released in the custom margins component.
- * Releases the dragged margin control.
- * @param {!PointerEvent} event Contains the position of the pointer.
- * @private
- */
- onPointerUp_: function(event) {
- const control =
- /** @type {!PrintPreviewMarginControlElement} */ (event.target);
- this.dragging_ = '';
- const posInPixels = this.translatePointerToPositionInPixels(
- new print_preview.Coordinate2d(event.x, event.y));
- const posInPts = this.posInPixelsToPts_(control, posInPixels);
- this.moveControlWithConstraints_(control, posInPts);
- this.setMargin_(control.side, posInPts);
- this.updateClippingMask(this.clipSize_);
- this.unlisten(control, 'pointercancel', 'onPointerUp_');
- this.unlisten(control, 'pointerup', 'onPointerUp_');
- this.unlisten(control, 'pointermove', 'onPointerMove_');
-
- this.fire('margin-drag-changed', false);
- },
+ // Do not set the controls invisible if the user is dragging or focusing
+ // the textbox for one of them.
+ if (invisible && (this.dragging_ != '' || this.textboxFocused_)) {
+ return;
+ }
- /**
- * @param {boolean} invisible Whether the margin controls should be
- * invisible.
- */
- setInvisible: function(invisible) {
- // Ignore changes if the margin controls are not available.
- if (!this.available_) {
- return;
- }
+ this.invisible_ = invisible;
+ },
- // Do not set the controls invisible if the user is dragging or focusing
- // the textbox for one of them.
- if (invisible && (this.dragging_ != '' || this.textboxFocused_)) {
- return;
- }
+ /**
+ * @param {!Event} e Contains information about what control fired the
+ * event.
+ * @private
+ */
+ onTextFocus_: function(e) {
+ this.textboxFocused_ = true;
+ const control =
+ /** @type {!PrintPreviewMarginControlElement} */ (e.target);
- this.invisible_ = invisible;
- },
+ const x = control.offsetLeft;
+ const y = control.offsetTop;
+ const isTopOrBottom = this.isTopOrBottom_(
+ /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
+ control.side));
+ const position = {};
+ // Extra padding, in px, to ensure the full textbox will be visible and
+ // not just a portion of it. Can't be less than half the width or height
+ // of the clip area for the computations below to work.
+ const padding = Math.min(
+ Math.min(this.clipSize_.width / 2, this.clipSize_.height / 2), 50);
+
+ // Note: clipSize_ gives the current visible area of the margin control
+ // container. The offsets of the controls are relative to the origin of
+ // this visible area.
+ if (isTopOrBottom) {
+ // For top and bottom controls, the horizontal position of the box is
+ // around halfway across the control's width.
+ position.x = Math.min(x + control.offsetWidth / 2 - padding, 0);
+ position.x = Math.max(
+ x + control.offsetWidth / 2 + padding - this.clipSize_.width,
+ position.x);
+ // For top and bottom controls, the vertical position of the box is
+ // nearly the same as the vertical position of the control.
+ position.y = Math.min(y - padding, 0);
+ position.y = Math.max(y - this.clipSize_.height + padding, position.y);
+ } else {
+ // For left and right controls, the horizontal position of the box is
+ // nearly the same as the horizontal position of the control.
+ position.x = Math.min(x - padding, 0);
+ position.x = Math.max(x - this.clipSize_.width + padding, position.x);
+ // For top and bottom controls, the vertical position of the box is
+ // around halfway up the control's height.
+ position.y = Math.min(y + control.offsetHeight / 2 - padding, 0);
+ position.y = Math.max(
+ y + control.offsetHeight / 2 + padding - this.clipSize_.height,
+ position.y);
+ }
- /**
- * @param {!Event} e Contains information about what control fired the event.
- * @private
- */
- onTextFocus_: function(e) {
- this.textboxFocused_ = true;
- const control = /** @type {!PrintPreviewMarginControlElement} */ (e.target);
-
- const x = control.offsetLeft;
- const y = control.offsetTop;
- const isTopOrBottom = this.isTopOrBottom_(
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
- control.side));
- const position = {};
- // Extra padding, in px, to ensure the full textbox will be visible and not
- // just a portion of it. Can't be less than half the width or height of the
- // clip area for the computations below to work.
- const padding = Math.min(
- Math.min(this.clipSize_.width / 2, this.clipSize_.height / 2), 50);
-
- // Note: clipSize_ gives the current visible area of the margin control
- // container. The offsets of the controls are relative to the origin of this
- // visible area.
- if (isTopOrBottom) {
- // For top and bottom controls, the horizontal position of the box is
- // around halfway across the control's width.
- position.x = Math.min(x + control.offsetWidth / 2 - padding, 0);
- position.x = Math.max(
- x + control.offsetWidth / 2 + padding - this.clipSize_.width,
- position.x);
- // For top and bottom controls, the vertical position of the box is nearly
- // the same as the vertical position of the control.
- position.y = Math.min(y - padding, 0);
- position.y = Math.max(y - this.clipSize_.height + padding, position.y);
- } else {
- // For left and right controls, the horizontal position of the box is
- // nearly the same as the horizontal position of the control.
- position.x = Math.min(x - padding, 0);
- position.x = Math.max(x - this.clipSize_.width + padding, position.x);
- // For top and bottom controls, the vertical position of the box is
- // around halfway up the control's height.
- position.y = Math.min(y + control.offsetHeight / 2 - padding, 0);
- position.y = Math.max(
- y + control.offsetHeight / 2 + padding - this.clipSize_.height,
- position.y);
- }
-
- this.fire('text-focus-position', position);
- },
+ this.fire('text-focus-position', position);
+ },
- /**
- * @param {string} side The margin side. Must be a CustomMarginsOrientation.
- * @param {number} marginValue New value for the margin in points.
- * @private
- */
- setMargin_: function(side, marginValue) {
- const marginSide =
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
- side);
- const oldMargins = /** @type {print_preview.MarginsSetting} */ (
- this.getSettingValue('customMargins'));
- const key = print_preview.MARGIN_KEY_MAP.get(marginSide);
- if (oldMargins[key] == marginValue) {
- return;
- }
- const newMargins = Object.assign({}, oldMargins);
- newMargins[key] = marginValue;
- this.setSetting('customMargins', newMargins);
- },
+ /**
+ * @param {string} side The margin side. Must be a CustomMarginsOrientation.
+ * @param {number} marginValue New value for the margin in points.
+ * @private
+ */
+ setMargin_: function(side, marginValue) {
+ const marginSide =
+ /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
+ side);
+ const oldMargins = /** @type {print_preview.MarginsSetting} */ (
+ this.getSettingValue('customMargins'));
+ const key = print_preview.MARGIN_KEY_MAP.get(marginSide);
+ if (oldMargins[key] == marginValue) {
+ return;
+ }
+ const newMargins = Object.assign({}, oldMargins);
+ newMargins[key] = marginValue;
+ this.setSetting('customMargins', newMargins);
+ },
- /**
- * @param {string} side The margin side. Must be a CustomMarginsOrientation.
- * @param {number} value The new margin value in points.
- * @return {number} The clipped margin value in points.
- * @private
- */
- clipAndRoundValue_: function(side, value) {
- const marginSide =
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
- side);
- if (value < 0) {
- return 0;
- }
- const Orientation = print_preview.ticket_items.CustomMarginsOrientation;
- let limit = 0;
- const margins = this.getSettingValue('customMargins');
- if (marginSide == Orientation.TOP) {
- limit = this.pageSize.height - margins.marginBottom - MINIMUM_DISTANCE;
- } else if (marginSide == Orientation.RIGHT) {
- limit = this.pageSize.width - margins.marginLeft - MINIMUM_DISTANCE;
- } else if (marginSide == Orientation.BOTTOM) {
- limit = this.pageSize.height - margins.marginTop - MINIMUM_DISTANCE;
- } else {
- assert(marginSide == Orientation.LEFT);
- limit = this.pageSize.width - margins.marginRight - MINIMUM_DISTANCE;
- }
- return Math.round(Math.min(value, limit));
- },
+ /**
+ * @param {string} side The margin side. Must be a CustomMarginsOrientation.
+ * @param {number} value The new margin value in points.
+ * @return {number} The clipped margin value in points.
+ * @private
+ */
+ clipAndRoundValue_: function(side, value) {
+ const marginSide =
+ /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
+ side);
+ if (value < 0) {
+ return 0;
+ }
+ const Orientation = print_preview.ticket_items.CustomMarginsOrientation;
+ let limit = 0;
+ const margins = this.getSettingValue('customMargins');
+ if (marginSide == Orientation.TOP) {
+ limit = this.pageSize.height - margins.marginBottom - MINIMUM_DISTANCE;
+ } else if (marginSide == Orientation.RIGHT) {
+ limit = this.pageSize.width - margins.marginLeft - MINIMUM_DISTANCE;
+ } else if (marginSide == Orientation.BOTTOM) {
+ limit = this.pageSize.height - margins.marginTop - MINIMUM_DISTANCE;
+ } else {
+ assert(marginSide == Orientation.LEFT);
+ limit = this.pageSize.width - margins.marginRight - MINIMUM_DISTANCE;
+ }
+ return Math.round(Math.min(value, limit));
+ },
- /**
- * @param {!CustomEvent<number>} e Event containing the new textbox value.
- * @private
- */
- onTextChange_: function(e) {
- const control =
- /** @type {!PrintPreviewMarginControlElement} */ (e.target);
- control.invalid = false;
- const clippedValue = this.clipAndRoundValue_(control.side, e.detail);
- control.setPositionInPts(clippedValue);
- this.setMargin_(control.side, clippedValue);
- },
+ /**
+ * @param {!CustomEvent<number>} e Event containing the new textbox value.
+ * @private
+ */
+ onTextChange_: function(e) {
+ const control =
+ /** @type {!PrintPreviewMarginControlElement} */ (e.target);
+ control.invalid = false;
+ const clippedValue = this.clipAndRoundValue_(control.side, e.detail);
+ control.setPositionInPts(clippedValue);
+ this.setMargin_(control.side, clippedValue);
+ },
- /**
- * @param {!CustomEvent<boolean>} e Event fired when a control's text field
- * is blurred. Contains information about whether the control is in an
- * invalid state.
- * @private
- */
- onTextBlur_: function(e) {
- if (e.detail /* detail is true if the control is in an invalid state */) {
+ /**
+ * @param {!CustomEvent<boolean>} e Event fired when a control's text field
+ * is blurred. Contains information about whether the control is in an
+ * invalid state.
+ * @private
+ */
+ onTextBlur_: function(e) {
const control =
/** @type {!PrintPreviewMarginControlElement} */ (e.target);
control.setTextboxValue(control.getPositionInPts());
- control.invalid = false;
- }
- this.textboxFocused_ = false;
- },
+ if (e.detail /* detail is true if the control is in an invalid state */) {
+ control.invalid = false;
+ }
+ this.textboxFocused_ = false;
+ },
- /**
- * @param {!PointerEvent} e Fired when pointerdown occurs on a margin control.
- * @private
- */
- onPointerDown_: function(e) {
- const control =
- /** @type {!PrintPreviewMarginControlElement} */ (e.target);
- if (!control.shouldDrag(e)) {
- return;
- }
-
- this.pointerStartPositionInPixels_ =
- new print_preview.Coordinate2d(e.x, e.y);
- this.marginStartPositionInPixels_ =
- new print_preview.Coordinate2d(control.offsetLeft, control.offsetTop);
- this.dragging_ =
- this.isTopOrBottom_(
- /** @type {print_preview.ticket_items.CustomMarginsOrientation} */ (
- control.side)) ?
- 'dragging-vertical' :
- 'dragging-horizontal';
- this.listen(control, 'pointercancel', 'onPointerUp_');
- this.listen(control, 'pointerup', 'onPointerUp_');
- this.listen(control, 'pointermove', 'onPointerMove_');
- control.setPointerCapture(e.pointerId);
-
- this.fire('margin-drag-changed', true);
- },
+ /**
+ * @param {!PointerEvent} e Fired when pointerdown occurs on a margin
+ * control.
+ * @private
+ */
+ onPointerDown_: function(e) {
+ const control =
+ /** @type {!PrintPreviewMarginControlElement} */ (e.target);
+ if (!control.shouldDrag(e)) {
+ return;
+ }
- /**
- * Set display:none after the opacity transition for the controls is done.
- * @private
- */
- onTransitionEnd_: function() {
- if (this.invisible_) {
- this.style.display = 'none';
- }
- },
+ this.pointerStartPositionInPixels_ =
+ new print_preview.Coordinate2d(e.x, e.y);
+ this.marginStartPositionInPixels_ =
+ new print_preview.Coordinate2d(control.offsetLeft, control.offsetTop);
+ this.dragging_ =
+ this.isTopOrBottom_(
+ /** @type {print_preview.ticket_items.CustomMarginsOrientation} */
+ (control.side)) ?
+ 'dragging-vertical' :
+ 'dragging-horizontal';
+ this.listen(control, 'pointercancel', 'onPointerUp_');
+ this.listen(control, 'pointerup', 'onPointerUp_');
+ this.listen(control, 'pointermove', 'onPointerMove_');
+ control.setPointerCapture(e.pointerId);
+
+ this.fire('margin-drag-changed', true);
+ },
- /**
- * Updates the translation transformation that translates pixel values in
- * the space of the HTML DOM.
- * @param {print_preview.Coordinate2d} translateTransform Updated value of
- * the translation transformation.
- */
- updateTranslationTransform: function(translateTransform) {
- if (!translateTransform.equals(this.translateTransform_)) {
- this.translateTransform_ = translateTransform;
- }
- },
+ /**
+ * Set display:none after the opacity transition for the controls is done.
+ * @private
+ */
+ onTransitionEnd_: function() {
+ if (this.invisible_) {
+ this.style.display = 'none';
+ }
+ },
- /**
- * Updates the scaling transform that scales pixels values to point values.
- * @param {number} scaleTransform Updated value of the scale transform.
- */
- updateScaleTransform: function(scaleTransform) {
- if (scaleTransform != this.scaleTransform_) {
- this.scaleTransform_ = scaleTransform;
- }
- },
+ /**
+ * Updates the translation transformation that translates pixel values in
+ * the space of the HTML DOM.
+ * @param {print_preview.Coordinate2d} translateTransform Updated value of
+ * the translation transformation.
+ */
+ updateTranslationTransform: function(translateTransform) {
+ if (!translateTransform.equals(this.translateTransform_)) {
+ this.translateTransform_ = translateTransform;
+ }
+ },
- /**
- * Clips margin controls to the given clip size in pixels.
- * @param {print_preview.Size} clipSize Size to clip the margin controls to.
- */
- updateClippingMask: function(clipSize) {
- if (!clipSize) {
- return;
- }
- this.clipSize_ = clipSize;
- this.notifyPath('clipSize_');
- },
+ /**
+ * Updates the scaling transform that scales pixels values to point values.
+ * @param {number} scaleTransform Updated value of the scale transform.
+ */
+ updateScaleTransform: function(scaleTransform) {
+ if (scaleTransform != this.scaleTransform_) {
+ this.scaleTransform_ = scaleTransform;
+ }
+ },
+
+ /**
+ * Clips margin controls to the given clip size in pixels.
+ * @param {print_preview.Size} clipSize Size to clip the margin controls to.
+ */
+ updateClippingMask: function(clipSize) {
+ if (!clipSize) {
+ return;
+ }
+ this.clipSize_ = clipSize;
+ this.notifyPath('clipSize_');
+ },
+ });
+
+ return {
+ MARGIN_KEY_MAP: MARGIN_KEY_MAP,
+ };
});
-})();
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 d4e1c49cfc0..3ed597c639c 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/plugin_proxy.js
@@ -2,42 +2,41 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('print_preview');
-/**
- * @typedef {{accessibility: Function,
- * documentLoadComplete: Function,
- * getHeight: Function,
- * getHorizontalScrollbarThickness: Function,
- * getPageLocationNormalized: Function,
- * getVerticalScrollbarThickness: Function,
- * getWidth: Function,
- * getZoomLevel: Function,
- * goToPage: Function,
- * grayscale: Function,
- * loadPreviewPage: Function,
- * onload: Function,
- * onPluginSizeChanged: Function,
- * onScroll: Function,
- * pageXOffset: Function,
- * pageYOffset: Function,
- * reload: Function,
- * resetPrintPreviewMode: Function,
- * sendKeyEvent: Function,
- * setPageNumbers: Function,
- * setPageXOffset: Function,
- * setPageYOffset: Function,
- * setZoomLevel: Function,
- * fitToHeight: Function,
- * fitToWidth: Function,
- * zoomIn: Function,
- * zoomOut: Function}}
- */
-print_preview.PDFPlugin;
-
cr.define('print_preview', function() {
'use strict';
/**
+ * @typedef {{accessibility: Function,
+ * documentLoadComplete: Function,
+ * getHeight: Function,
+ * getHorizontalScrollbarThickness: Function,
+ * getPageLocationNormalized: Function,
+ * getVerticalScrollbarThickness: Function,
+ * getWidth: Function,
+ * getZoomLevel: Function,
+ * goToPage: Function,
+ * grayscale: Function,
+ * loadPreviewPage: Function,
+ * onload: Function,
+ * onPluginSizeChanged: Function,
+ * onScroll: Function,
+ * pageXOffset: Function,
+ * pageYOffset: Function,
+ * reload: Function,
+ * resetPrintPreviewMode: Function,
+ * sendKeyEvent: Function,
+ * setPageNumbers: Function,
+ * setPageXOffset: Function,
+ * setPageYOffset: Function,
+ * setZoomLevel: Function,
+ * fitToHeight: Function,
+ * fitToWidth: Function,
+ * zoomIn: Function,
+ * zoomOut: Function}}
+ */
+ let PDFPlugin;
+
+ /**
* An interface to the PDF plugin.
*/
class PluginProxy {
@@ -185,5 +184,8 @@ cr.define('print_preview', function() {
let instance = null;
// Export
- return {PluginProxy: PluginProxy};
+ return {
+ PDFPlugin: PDFPlugin,
+ PluginProxy: PluginProxy,
+ };
});
diff --git a/chromium/chrome/browser/resources/protobufs/OWNERS b/chromium/chrome/browser/resources/protobufs/OWNERS
index 27806953f99..f93bbac403b 100644
--- a/chromium/chrome/browser/resources/protobufs/OWNERS
+++ b/chromium/chrome/browser/resources/protobufs/OWNERS
@@ -1,2 +1,4 @@
+drubery@chromium.org
meacer@chromium.org
-nparker@chromium.org \ No newline at end of file
+nparker@chromium.org
+vakh@chromium.org
diff --git a/chromium/chrome/browser/resources/reset_password/BUILD.gn b/chromium/chrome/browser/resources/reset_password/BUILD.gn
index 2a2f75f6e12..d464dd90c25 100644
--- a/chromium/chrome/browser/resources/reset_password/BUILD.gn
+++ b/chromium/chrome/browser/resources/reset_password/BUILD.gn
@@ -12,7 +12,7 @@ js_type_check("closure_compile") {
js_library("reset_password") {
deps = [
- "//chrome/browser/ui/webui/reset_password:mojo_bindings_js_externs",
+ "//chrome/browser/ui/webui/reset_password:mojo_bindings_js_library_for_compile",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:util",
]
diff --git a/chromium/chrome/browser/resources/reset_password/reset_password.js b/chromium/chrome/browser/resources/reset_password/reset_password.js
index 15611b4d0e8..b08c7c32875 100644
--- a/chromium/chrome/browser/resources/reset_password/reset_password.js
+++ b/chromium/chrome/browser/resources/reset_password/reset_password.js
@@ -8,16 +8,16 @@
*/
(function() {
-/** @type {mojom.ResetPasswordHandlerProxy} */
-let uiHandler;
+/** @type {mojom.ResetPasswordHandlerRemote} */
+let pageHandler;
function initialize() {
- uiHandler = mojom.ResetPasswordHandler.getProxy();
+ pageHandler = mojom.ResetPasswordHandler.getRemote();
/** @type {?HTMLElement} */
const resetPasswordButton = $('reset-password-button');
resetPasswordButton.addEventListener('click', function() {
- uiHandler.handlePasswordReset();
+ pageHandler.handlePasswordReset();
});
}
diff --git a/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py b/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py
new file mode 100644
index 00000000000..012844a2057
--- /dev/null
+++ b/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py
@@ -0,0 +1,56 @@
+# 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.
+
+"""Presubmit checks for Safety Tips proto for the component updater.
+"""
+
+"""Returns true if any line in changed_contents contains the string |s|.
+|changed_contents| is a tuple containing (line number, line text) pairs.
+"""
+def ContainsLine(changed_contents, s):
+ for _, line in changed_contents:
+ if line.strip().startswith(s):
+ return True
+ return False
+
+def CheckVersionUpdatedInProto(input_api, output_api):
+ def IsSafetyTipProto(x):
+ return (input_api.os_path.basename(x.LocalPath()) ==
+ 'safety_tips.asciipb')
+
+ safety_tips_proto = input_api.AffectedFiles(file_filter=IsSafetyTipProto)
+ if not safety_tips_proto:
+ return []
+
+ contents = safety_tips_proto[0].ChangedContents()
+ # Must not have any changes containing flagged_page:
+ if ContainsLine(contents, 'flagged_page:'):
+ return [output_api.PresubmitError(
+ 'Do not check in the full safety_tips.asciipb proto. '
+ 'Only increment |version_id|.')]
+
+ # This proto should not contain any actually-flagged pages. ContainsLine
+ # checks if any line *starts with* the given string.
+ if ContainsLine(contents, 'flagged_page:'):
+ return [output_api.PresubmitError(
+ 'Remove entries from Chromium safety_tips.asciipb before submitting.')]
+
+ # It's enticing to do something fancy like checking whether the ID was in fact
+ # incremented or whether this is a whitespace-only or comment-only change.
+ # However, currently deleted lines don't show up in ChangedContents() and
+ # attempting to parse the asciipb file any more than we are doing above is
+ # likely not worth the trouble.
+ #
+ # At worst, the submitter can skip the presubmit check on upload if it isn't
+ # correct.
+ if not ContainsLine(contents, 'version_id:'):
+ return [output_api.PresubmitError(
+ 'Increment |version_id| in safety_tips.asciipb if you are '
+ 'updating the file types proto.')]
+
+ return []
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return CheckVersionUpdatedInProto(input_api, output_api)
diff --git a/chromium/chrome/browser/resources/safety_tips/README.md b/chromium/chrome/browser/resources/safety_tips/README.md
new file mode 100644
index 00000000000..b02c20d0730
--- /dev/null
+++ b/chromium/chrome/browser/resources/safety_tips/README.md
@@ -0,0 +1 @@
+See go/safety-tips-component-update for Safety Tips component update playbook.
diff --git a/chromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py b/chromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py
index a12e8e78eb0..e4ec99a4e3e 100755
--- a/chromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py
+++ b/chromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py
@@ -15,6 +15,9 @@ import sys
# Subdirectory to be copied to Google Cloud Storage. Contains a copy of the
# generated proto under a versioned directory.
+# TODO(meacer): Remove this. Safety tips does not read the proto from a local
+# resource bundle, it only uses the proto passed from component updater. It does
+# not need two copies of the file.
GS_COPY_DIR = "gs_copy"
# Import the binary proto generator. Walks up to the root of the source tree
@@ -40,11 +43,14 @@ class SafetyTipsProtoGenerator(BinaryProtoGenerator):
def ValidatePb(self, opts, pb):
assert pb.version_id > 0
- assert len(pb.flagged_page) > 0
for flagged_page in pb.flagged_page:
- assert flagged_page.url
+ assert flagged_page.pattern
assert flagged_page.type != safety_tips_pb2.FlaggedPage.UNKNOWN
+ flagged_patterns = [page.pattern for page in pb.flagged_page]
+ assert sorted(flagged_patterns) == flagged_patterns, (
+ "Please sort flagged_page entries by pattern.")
+
def ProcessPb(self, opts, pb):
binary_pb_str = pb.SerializeToString()
outfile = os.path.join(opts.outdir, opts.outbasename)
diff --git a/chromium/chrome/browser/resources/safety_tips/push_proto.py b/chromium/chrome/browser/resources/safety_tips/push_proto.py
new file mode 100755
index 00000000000..2404cb96399
--- /dev/null
+++ b/chromium/chrome/browser/resources/safety_tips/push_proto.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+# Copyright 2018 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.
+
+# Build and push the {vers}/all/ssl_error_assistant.pb file to GCS so
+# that the component update system will pick it up and push it to users.
+# See README.md before running this.
+#
+# Requires ninja and gsutil to be in the user's path.
+
+import optparse
+import os
+import shutil
+import subprocess
+import sys
+
+
+DEST_BUCKET = 'gs://chrome-components-safety-tips'
+RESOURCE_SUBDIR = 'chrome/browser/resources/safety_tips'
+
+# Subdirectory to be copied to Google Cloud Storage. Contains a copy of the
+# generated proto under a versioned directory.
+GS_COPY_DIR = "gs_copy"
+
+# TODO(meacer): This is pretty much a duplicate of
+# chrome/browser/safe_browsing/push_file_type_proto.py. Consider
+# refactoring and reusing code.
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-d', '--dir',
+ help='An up-to-date GN/Ninja build directory, '
+ 'such as ./out/Debug')
+
+ (opts, _) = parser.parse_args()
+ if opts.dir is None:
+ parser.print_help()
+ return 1
+
+ # Clear out the target dir before we build so we can be sure we've got
+ # the freshest version.
+ target_dir = os.path.join(opts.dir, "gen", RESOURCE_SUBDIR)
+ if os.path.isdir(target_dir):
+ shutil.rmtree(target_dir)
+
+ gn_command = ['ninja',
+ '-C', opts.dir,
+ RESOURCE_SUBDIR + ':make_safety_tips_protobuf']
+ print "Running the following"
+ print " " + (' '.join(gn_command))
+ if subprocess.call(gn_command):
+ print "Ninja failed."
+ return 1
+
+ # Use the versioned files under the copy directory to push to the GCS bucket.
+ copy_dir = os.path.join(target_dir, GS_COPY_DIR)
+ os.chdir(copy_dir)
+
+ # Sanity check that there is a versioned copy under the directory.
+ dirs = os.listdir('.')
+ assert len(dirs) == 1 and dirs[0].isdigit(), (
+ "There must be a single versioned dir under " + copy_dir)
+
+ # Push the files with their directories, in the form
+ # {vers}/{platform}/download_file_types.pb
+ # Don't overwrite existing files, in case we forgot to increment the
+ # version.
+ version_dir = dirs[0]
+ command = ['gsutil', 'cp', '-Rn', version_dir, DEST_BUCKET]
+
+ print '\nGoing to run the following command'
+ print ' ', ' '.join(command)
+ print '\nIn directory'
+ print ' ', copy_dir
+ print '\nWhich should push the following files'
+ expected_files = [os.path.join(dp, f) for dp, _, fn in
+ os.walk(version_dir) for f in fn]
+ for f in expected_files:
+ print ' ', f
+
+ shall = raw_input('\nAre you sure (y/N) ').lower() == 'y'
+ if not shall:
+ print 'aborting'
+ return 1
+ return subprocess.call(command)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb b/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
index 9306e6c7a27..64b7f997870 100644
--- a/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
+++ b/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
@@ -2,16 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-# Placeholder for list of known bad URLs.
-# This file must be kept as-is and the full list must not be checked in to
-# Chromium source. When you want to update it, overwrite it locally, generate
-# and push the protobuffer to the storage bucket but do not check in the
-# changes.
+# Placeholder for list of known bad patterns.
+# This file must be kept as-is except for version_id. The full list must not be
+# checked in to Chromium source. When you want to update it, overwrite it
+# locally, generate and push the protobuffer to the storage bucket but do not
+# check in the changes.
-version_id: 1
+version_id: 4
# See chrome/browser/lookalikes/safety_tips.proto for the full format.
-flagged_page {
- url: "http://example.test/test-path-for-safety-tips/test.html"
- type: BAD_REP
-}
+# These entries must be sorted alphabetically by pattern.
+
+# Example entry:
+# flagged_page {
+# pattern: "example.test/test-path-for-safety-tips/test.html"
+# type: BAD_REP
+#}
diff --git a/chromium/chrome/browser/resources/set_as_default_browser.css b/chromium/chrome/browser/resources/set_as_default_browser.css
deleted file mode 100644
index 9fb82d5c72a..00000000000
--- a/chromium/chrome/browser/resources/set_as_default_browser.css
+++ /dev/null
@@ -1,159 +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. */
-
-/* The main (outer) container. */
-#metro-setup-outer-container {
- -webkit-box-align: center;
- -webkit-box-orient: vertical;
- -webkit-box-pack: start;
- background-color: rgba(255, 255, 255, 0.75);
- bottom: 0;
- display: -webkit-box;
- left: 0;
- overflow: auto;
- position: fixed;
- right: 0;
- top: 0;
- transition: 200ms opacity;
-}
-
-/* The page block within the outer container. */
-#metro-setup-outer-container .page {
- -webkit-box-orient: vertical;
- background: white;
- background-color: white;
- border-radius: 3px;
- color: #333;
- display: -webkit-box;
- min-width: 40px;
- padding-top: 90px;
- position: relative;
- user-select: none;
- width: 500px;
-}
-
-#metro-setup-outer-container .page .content-area {
- -webkit-box-flex: 1;
- margin: 0;
- overflow: auto;
- padding: 0;
-}
-
-#metro-setup-overlay {
- background-color: transparent;
- margin: 0;
- width: 100%;
-}
-
-/* Page Title. */
-#metro-title-container {
- display: block;
- margin: 37px 44px 35px;
- text-align: center;
-}
-
-#metro-setup-outer-container .page h1 {
- border-bottom: 0;
- color: #323232;
- font-size: 300%;
- font-weight: normal;
- margin: 0;
- padding-bottom: 0;
- padding-top: 0;
- text-align: center;
-}
-
-#metro-setup-outer-container .page h2 {
- border-bottom: 0;
- color: #787878;
- font-size: 150%;
- font-weight: normal;
- margin-bottom: 84px;
- margin-top: 15px;
- text-align: center;
-}
-
-#metro-setup-overlay .content-area {
- padding: 10px 15px;
- text-align: end;
-}
-
-/* Action buttons. */
-#metro-action-box button {
- border-radius: 2px;
- display: inline-block;
- font-size: 13px;
- height: 32px;
- line-height: 27px;
- margin-inline-end: 0.4em;
- margin-inline-start: 0;
- margin-top: 0;
- min-width: 80px;
- transition: all 218ms;
- user-select: none;
-}
-
-#metro-action-box button:hover {
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
- transition: all 0ms;
-}
-
-#metro-action-box button:focus {
- box-shadow: inset 0 0 0 1px white;
- outline: none;
- z-index: 4 !important;
-}
-
-#metro-action-box button:active,
-#metro-action-box button:focus:active {
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
-}
-
-#metro-action-box button:focus:hover {
- box-shadow: inset 0 0 0 1px white, 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-
-#metro-action-box button[disabled],
-#metro-action-box button[disabled]:hover,
-#metro-action-box button[disabled]:active {
- background-color: rgb(77, 144, 254);
- border: 1px solid rgb(48, 121, 237);
- box-shadow: none;
- color: white;
- opacity: 0.5;
-}
-
-/* Launch button has a special look-and-feel. */
-#metro-action-box #launch-button {
- background-image: -webkit-linear-gradient(top, rgb(77, 144, 254),
- rgb(71, 135, 237));
- border: 1px solid rgb(48, 121, 237);
- color: white;
- font-weight: bold;
-}
-
-#metro-action-box #launch-button:hover {
- background-image: -webkit-linear-gradient(top, rgb(77, 144, 254),
- rgb(53, 122, 232));
- border-color: rgb(47, 91, 183);
- color: white;
-}
-
-#metro-action-box #launch-button:focus {
- border-color: rgb(77, 144, 254);
- outline: none;
- z-index: 4 !important;
-}
-
-.button-strip {
- margin: 1px;
- text-align: center;
-}
-
-#chrome-logo-box {
- bottom: 30px;
- position: absolute;
- text-align: center;
- width: 100%;
-}
diff --git a/chromium/chrome/browser/resources/set_as_default_browser.html b/chromium/chrome/browser/resources/set_as_default_browser.html
deleted file mode 100644
index 8f65526a95d..00000000000
--- a/chromium/chrome/browser/resources/set_as_default_browser.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!doctype html>
-<!-- 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. -->
-<html dir="$i18n{textdirection}" lang="$i18n{language}">
-<head>
-<meta charset="utf-8">
-<title>$i18n{pageTitle}</title>
-<script src="chrome://resources/js/cr.js"></script>
-<script src="chrome://resources/js/util.js"></script>
-<script src="chrome://resources/js/cr/event_target.js"></script>
-<script src="set_as_default_browser.js"></script>
-<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
-<link rel="stylesheet" href="chrome://resources/css/widgets.css">
-<link rel="stylesheet" href="set_as_default_browser.css">
-</head>
-<body>
-<div id="metro-setup-outer-container">
- <div id="metro-setup-overlay" class="page">
- <div>
- <div class="content-area">
- <h1>$i18n{flowTitle}</h1>
- <h2>$i18n{flowDescription}</h2>
- </div>
- <div id="metro-action-box" class="content-area">
- <div class="button-strip">
- <button id="launch-button" class="custom-appearance">
- $i18n{flowNext}
- </button>
- </div>
- </div>
- </div>
- </div>
- <div id="chrome-logo-box">
- <img src="chrome-logo-faded.png" alt="$i18n{chromeLogoString}">
- </div>
-</div>
-</body>
-</html>
diff --git a/chromium/chrome/browser/resources/set_as_default_browser.js b/chromium/chrome/browser/resources/set_as_default_browser.js
deleted file mode 100644
index 254704b5e74..00000000000
--- a/chromium/chrome/browser/resources/set_as_default_browser.js
+++ /dev/null
@@ -1,16 +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.
-
-(function() {
-// Since all we want here is forwarding of certain commands, all can be done
-// in the anonymous function's scope.
-
-function wireUpWindow() {
- $('launch-button').addEventListener('click', function() {
- chrome.send('SetAsDefaultBrowser:LaunchSetDefaultBrowserFlow');
- });
-}
-
-window.addEventListener('DOMContentLoaded', wireUpWindow);
-})();
diff --git a/chromium/chrome/browser/resources/settings/BUILD.gn b/chromium/chrome/browser/resources/settings/BUILD.gn
index 90c81d10457..4ba0dd05e72 100644
--- a/chromium/chrome/browser/resources/settings/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/BUILD.gn
@@ -106,7 +106,6 @@ group("closure_compile") {
if (is_chromeos) {
deps += [
"android_apps_page:closure_compile",
- "app_management_page:closure_compile",
"bluetooth_page:closure_compile",
"chromeos:closure_compile",
"crostini_page:closure_compile",
diff --git a/chromium/chrome/browser/resources/settings/OWNERS b/chromium/chrome/browser/resources/settings/OWNERS
index a34bf8b5f11..de56e9e6644 100644
--- a/chromium/chrome/browser/resources/settings/OWNERS
+++ b/chromium/chrome/browser/resources/settings/OWNERS
@@ -6,4 +6,7 @@ michaelpg@chromium.org
stevenjb@chromium.org
tommycli@chromium.org
+# Chrome OS Settings
+per-file *os_settings*=file://chrome/browser/resources/settings/chromeos/OWNERS
+
# COMPONENT: UI>Settings
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/BUILD.gn b/chromium/chrome/browser/resources/settings/a11y_page/BUILD.gn
index cb0f25da20a..81f68e46981 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/a11y_page/BUILD.gn
@@ -52,10 +52,12 @@ js_library("manage_a11y_page") {
js_library("switch_access_subpage") {
deps = [
"..:route",
+ "../prefs:prefs_behavior",
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
+ externs_list = [ "$externs_path/settings_private.js" ]
}
js_library("tts_subpage") {
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
index 74d602e6f8e..078fc8f2161 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -19,43 +19,24 @@
<dom-module id="settings-a11y-page">
<template>
<style include="settings-shared"></style>
- <template is="dom-if" if="[[showCaptionSettings_]]">
- <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}"
- on-click="onCaptionsClick_">
- </cr-link-row>
- </template>
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="a11y" focus-config="[[focusConfig_]]">
-<if expr="not chromeos">
<div route-path="default">
- <settings-toggle-button
- id="a11yImageLabels"
- hidden$="[[!showAccessibilityLabelsSetting_]]"
- pref="{{prefs.settings.a11y.enable_accessibility_image_labels}}"
- on-change="onToggleAccessibilityImageLabels_"
- label="$i18n{accessibleImageLabelsTitle}"
- sub-label="$i18n{accessibleImageLabelsSubtitle}">
- </settings-toggle-button>
- <cr-link-row class="hr" label="$i18n{moreFeaturesLink}"
- on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}"
- external>
- </cr-link-row>
- </div>
-</if>
-<if expr="chromeos or is_linux or is_win">
- <template is="dom-if" if="[[showCaptionSettings_]]">
- <template is="dom-if" route-path="/captions">
- <settings-subpage
- associated-control="[[$$('#captions')]]"
- page-title="$i18n{captionsTitle}">
- <settings-captions prefs="{{prefs}}"></settings-captions>
- </settings-subpage>
- </template>
- </template>
+ <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}"
+ on-click="onCaptionsClick_" external$="[[captionSettingsOpensExternally_]]">
+ </cr-link-row>
+<if expr="not chromeos">
+ <settings-toggle-button
+ id="a11yImageLabels"
+ hidden$="[[!showAccessibilityLabelsSetting_]]"
+ pref="{{prefs.settings.a11y.enable_accessibility_image_labels}}"
+ on-change="onToggleAccessibilityImageLabels_"
+ label="$i18n{accessibleImageLabelsTitle}"
+ sub-label="$i18n{accessibleImageLabelsSubtitle}">
+ </settings-toggle-button>
</if>
<if expr="chromeos">
- <template is="dom-if" if="[[pageVisibility.webstoreLink]]">
- <div route-path="default">
+ <template is="dom-if" if="[[pageVisibility.webstoreLink]]">
<settings-toggle-button
id="a11yImageLabels"
hidden$="[[!showAccessibilityLabelsSetting_]]"
@@ -73,7 +54,26 @@
on-click="onManageAccessibilityFeaturesTap_"
sub-label="$i18n{moreFeaturesLinkDescription}">
</cr-link-row>
- </div>
+ </template>
+</if>
+ <cr-link-row class="hr" label="$i18n{moreFeaturesLink}"
+ on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}"
+ hidden="[[pageVisibility.webstoreLink]]" external>
+ </cr-link-row>
+ </div>
+<if expr="not is_macosx">
+ <template is="dom-if" if="[[showCaptionSettings_]]">
+ <template is="dom-if" route-path="/captions">
+ <settings-subpage
+ associated-control="[[$$('#captions')]]"
+ page-title="$i18n{captionsTitle}">
+ <settings-captions prefs="{{prefs}}"></settings-captions>
+ </settings-subpage>
+ </template>
+ </template>
+</if>
+<if expr="chromeos">
+ <template is="dom-if" if="[[pageVisibility.webstoreLink]]">
<template is="dom-if" route-path="/manageAccessibility">
<settings-subpage
associated-control="[[$$('#subpage-trigger')]]"
@@ -86,8 +86,7 @@
<settings-subpage
associated-control="[[$$('#subpage-trigger')]]"
page-title="$i18n{manageTtsSettings}">
- <settings-tts-subpage prefs="{{prefs}}">
- </settings-tts-subpage>
+ <settings-tts-subpage prefs="{{prefs}}"></settings-tts-subpage>
</settings-subpage>
</template>
<template is="dom-if" route-path="/manageAccessibility/switchAccess">
@@ -100,12 +99,6 @@
</template>
</if>
</settings-animated-pages>
-<if expr="chromeos">
- <cr-link-row class="hr" label="$i18n{moreFeaturesLink}"
- on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}"
- hidden="[[pageVisibility.webstoreLink]]" external>
- </cr-link-row>
-</if>
</template>
<script src="a11y_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
index 6629ff75429..31045680975 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -67,6 +67,26 @@ Polymer({
},
},
+ /**
+ * Whether the caption settings link opens externally.
+ * @private {boolean}
+ */
+ captionSettingsOpensExternally_: {
+ type: Boolean,
+ value: function() {
+ let opensExternally = false;
+ // <if expr="is_macosx">
+ opensExternally = true;
+ // </if>
+
+ // <if expr="is_win">
+ opensExternally = loadTimeData.getBoolean('isWindows10OrNewer');
+ // </if>
+
+ return opensExternally;
+ },
+ },
+
// <if expr="chromeos">
/**
* Whether to show experimental accessibility features.
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.html b/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.html
index d3d305b9c42..a894a919576 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.html
@@ -7,83 +7,102 @@
<dom-module id="settings-captions">
<template>
- <style include="settings-shared"></style>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsTextSize}</div>
- <settings-dropdown-menu id="captionsTextSize"
- label="$i18n{captionsTextSize}"
- pref="{{prefs.accessibility.captions.text_size}}"
- menu-options="[[textSizeOptions_]]">
- </settings-dropdown-menu>
+ <style include="settings-shared">
+ .preview-box {
+ align-items: center;
+ background-image:
+ url(chrome://theme/IDR_ACCESSIBILITY_CAPTIONS_PREVIEW_BACKGROUND);
+ background-position: center;
+ background-size: cover;
+ display: flex;
+ height: 112px;
+ justify-content: center;
+ margin: 0 var(--cr-section-padding) var(--cr-section-padding);
+ text-align: center;
+ }
+ </style>
+ <div class="settings-box first">
+ <h2 class="start">$i18n{captionsPreview}</h2>
</div>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsTextFont}</div>
- <settings-dropdown-menu id="captionsTextFont"
- label="$i18n{captionsTextFont}"
- pref="{{prefs.accessibility.captions.text_font}}"
- menu-options="[[textFontOptions_]]">
- </settings-dropdown-menu>
+ <div class="preview-box">
+ <span style="
+ font-size:[[prefs.accessibility.captions.text_size.value]];
+ font-family:[[prefs.accessibility.captions.text_font.value]];
+ background-color: [[computeBackgroundColor_(
+ prefs.accessibility.captions.background_opacity.value,
+ prefs.accessibility.captions.background_color.value)]];
+ color: [[computeTextColor_(
+ prefs.accessibility.captions.text_opacity.value,
+ prefs.accessibility.captions.text_color.value)]];
+ text-shadow: [[prefs.accessibility.captions.text_shadow.value]];
+ padding: [[computePadding_(
+ prefs.accessibility.captions.text_size.value)]]">
+ $i18n{quickBrownFox}
+ </span>
</div>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsTextColor}</div>
- <settings-dropdown-menu id="captionsTextColor"
- label="$i18n{captionsTextColor}"
- pref="{{prefs.accessibility.captions.text_color}}"
- menu-options="[[colorOptions_]]">
- </settings-dropdown-menu>
- </div>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsTextOpacity}</div>
- <settings-slider id="captionsTextOpacity"
- ticks="[[textOpacityRange_]]"
- label-min="$i18n{captionsOpacityMin}"
- label-max="$i18n{captionsOpacityMax}"
- pref="{{prefs.accessibility.captions.text_opacity}}">
- </settings-slider>
- </div>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsTextShadow}</div>
- <settings-dropdown-menu id="captionsTextShadow"
- label="$i18n{captionsTextShadow}"
- pref="{{prefs.accessibility.captions.text_shadow}}"
- menu-options="[[textShadowOptions_]]">
- </settings-dropdown-menu>
- </div>
- <div class="settings-box">
- <div class="start settings-box-text">$i18n{captionsBackgroundColor}</div>
- <settings-dropdown-menu id="captionsBackgroundColor"
- label="$i18n{captionsBackgroundColor}"
- pref="{{prefs.accessibility.captions.background_color}}"
- menu-options="[[colorOptions_]]">
- </settings-dropdown-menu>
- </div>
- <div class="settings-box">
- <div class="start settings-box-text">
- $i18n{captionsBackgroundOpacity}
- </div>
- <settings-slider id="captionsBackgroundOpacity"
- ticks="[[textOpacityRange_]]"
- label-min="$i18n{captionsOpacityMin}"
- label-max="$i18n{captionsOpacityMax}"
- pref="{{prefs.accessibility.captions.background_opacity}}">
- </settings-slider>
+ <div class="settings-box continuation">
+ <h2 class="start">$i18n{captionsSettings}</h2>
</div>
<div class="list-frame">
+ <div class="list-item underbar first">
+ <div class="start settings-box-text">$i18n{captionsTextSize}</div>
+ <settings-dropdown-menu id="captionsTextSize"
+ label="$i18n{captionsTextSize}"
+ pref="{{prefs.accessibility.captions.text_size}}"
+ menu-options="[[textSizeOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="list-item underbar">
+ <div class="start settings-box-text">$i18n{captionsTextFont}</div>
+ <settings-dropdown-menu id="captionsTextFont"
+ label="$i18n{captionsTextFont}"
+ pref="{{prefs.accessibility.captions.text_font}}"
+ menu-options="[[textFontOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="list-item underbar">
+ <div class="start settings-box-text">$i18n{captionsTextColor}</div>
+ <settings-dropdown-menu id="captionsTextColor"
+ label="$i18n{captionsTextColor}"
+ pref="{{prefs.accessibility.captions.text_color}}"
+ menu-options="[[colorOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="list-item underbar">
+ <div class="start settings-box-text">$i18n{captionsTextOpacity}</div>
+ <settings-dropdown-menu id="captionsTextOpacity"
+ label="$i18n{captionsTextOpacity}"
+ pref="{{prefs.accessibility.captions.text_opacity}}"
+ menu-options="[[textOpacityOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="list-item underbar">
+ <div class="start settings-box-text">$i18n{captionsTextShadow}</div>
+ <settings-dropdown-menu id="captionsTextShadow"
+ label="$i18n{captionsTextShadow}"
+ pref="{{prefs.accessibility.captions.text_shadow}}"
+ menu-options="[[textShadowOptions_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="list-item underbar">
+ <div class="start settings-box-text">
+ $i18n{captionsBackgroundColor}
+ </div>
+ <settings-dropdown-menu id="captionsBackgroundColor"
+ label="$i18n{captionsBackgroundColor}"
+ pref="{{prefs.accessibility.captions.background_color}}"
+ menu-options="[[colorOptions_]]">
+ </settings-dropdown-menu>
+ </div>
<div class="list-item">
- <span style="
- font-size:[[prefs.accessibility.captions.text_size.value]];
- font-family:[[prefs.accessibility.captions.text_font.value]];
- background-color: [[computeBackgroundColor_(
- prefs.accessibility.captions.background_opacity.value,
- prefs.accessibility.captions.background_color.value)]];
- color: [[computeTextColor_(
- prefs.accessibility.captions.text_opacity.value,
- prefs.accessibility.captions.text_color.value)]];
- text-shadow: [[prefs.accessibility.captions.text_shadow.value]];
- padding: [[computePadding_(
- prefs.accessibility.captions.text_size.value)]]">
- $i18n{quickBrownFox}
- </span>
+ <div class="start settings-box-text">
+ $i18n{captionsBackgroundOpacity}
+ </div>
+ <settings-dropdown-menu id="captionsBackgroundOpacity"
+ label="$i18n{captionsBackgroundOpacity}"
+ pref="{{prefs.accessibility.captions.background_opacity}}"
+ menu-options="[[backgroundOpacityOptions_]]">
+ </settings-dropdown-menu>
</div>
</div>
</template>
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.js b/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.js
index df973af40cd..ca625a3be4f 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/captions_subpage.js
@@ -9,21 +9,6 @@
(function() {
'use strict';
-
-/** @type {!Array<number>} */
-const TEXT_OPACITY_RANGE = [
- 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50,
- 55, 60, 65, 70, 75, 80, 85, 90, 95, 100
-];
-
-/**
- * @param {!Array<number>} ticks
- * @return {!Array<!cr_slider.SliderTick>}
- */
-function ticksWithLabels(ticks) {
- return ticks.map(x => ({label: `${x}`, value: x}));
-}
-
Polymer({
is: 'settings-captions',
@@ -36,34 +21,26 @@ Polymer({
},
/**
- * List of fonts populated by the fonts browser proxy.
- * @private {!DropdownMenuOptionList} */
- textFontOptions_: Object,
-
- /**
- * Reasonable, text opacity range.
- * @private {!Array<!cr_slider.SliderTick>}
- */
- textOpacityRange_: {
- readOnly: true,
- type: Array,
- value: ticksWithLabels(TEXT_OPACITY_RANGE),
- },
-
- /**
- * List of options for the text size drop-down menu.
+ * List of options for the background opacity drop-down menu.
* @type {!DropdownMenuOptionList}
*/
- textSizeOptions_: {
+ backgroundOpacityOptions_: {
readOnly: true,
type: Array,
value: function() {
return [
- {value: '50%', name: loadTimeData.getString('verySmall')},
- {value: '75%', name: loadTimeData.getString('small')},
- {value: '', name: loadTimeData.getString('medium')}, // Default = 100%
- {value: '150%', name: loadTimeData.getString('large')},
- {value: '200%', name: loadTimeData.getString('veryLarge')},
+ {
+ value: 100, // Default
+ name: loadTimeData.getString('captionsOpacityOpaque')
+ },
+ {
+ value: 50,
+ name: loadTimeData.getString('captionsOpacitySemiTransparent')
+ },
+ {
+ value: 0,
+ name: loadTimeData.getString('captionsOpacityTransparent')
+ },
];
},
},
@@ -77,18 +54,30 @@ Polymer({
type: Array,
value: function() {
return [
- {value: '', name: loadTimeData.getString('captionsDefaultSetting')},
- {value: '0,0,0', name: loadTimeData.getString('captionsColorBlack')},
+ {
+ value: '',
+ name: loadTimeData.getString('captionsDefaultSetting')
+ },
+ {
+ value: '0,0,0',
+ name: loadTimeData.getString('captionsColorBlack')
+ },
{
value: '255,255,255',
name: loadTimeData.getString('captionsColorWhite')
},
- {value: '255,0,0', name: loadTimeData.getString('captionsColorRed')},
+ {
+ value: '255,0,0',
+ name: loadTimeData.getString('captionsColorRed')
+ },
{
value: '0,255,0',
name: loadTimeData.getString('captionsColorGreen')
},
- {value: '0,0,255', name: loadTimeData.getString('captionsColorBlue')},
+ {
+ value: '0,0,255',
+ name: loadTimeData.getString('captionsColorBlue')
+ },
{
value: '255,255,0',
name: loadTimeData.getString('captionsColorYellow')
@@ -106,6 +95,36 @@ Polymer({
},
/**
+ * List of fonts populated by the fonts browser proxy.
+ * @private {!DropdownMenuOptionList} */
+ textFontOptions_: Object,
+
+ /**
+ * List of options for the text opacity drop-down menu.
+ * @type {!DropdownMenuOptionList}
+ */
+ textOpacityOptions_: {
+ readOnly: true,
+ type: Array,
+ value: function() {
+ return [
+ {
+ value: 100, // Default
+ name: loadTimeData.getString('captionsOpacityOpaque')
+ },
+ {
+ value: 50,
+ name: loadTimeData.getString('captionsOpacitySemiTransparent')
+ },
+ {
+ value: 10,
+ name: loadTimeData.getString('captionsOpacityTransparent')
+ },
+ ];
+ },
+ },
+
+ /**
* List of options for the text shadow drop-down menu.
* @type {!DropdownMenuOptionList}
*/
@@ -135,6 +154,24 @@ Polymer({
];
},
},
+
+ /**
+ * List of options for the text size drop-down menu.
+ * @type {!DropdownMenuOptionList}
+ */
+ textSizeOptions_: {
+ readOnly: true,
+ type: Array,
+ value: function() {
+ return [
+ {value: '25%', name: loadTimeData.getString('verySmall')},
+ {value: '50%', name: loadTimeData.getString('small')},
+ {value: '', name: loadTimeData.getString('medium')}, // Default = 100%
+ {value: '150%', name: loadTimeData.getString('large')},
+ {value: '200%', name: loadTimeData.getString('veryLarge')},
+ ];
+ },
+ },
},
/** @private {?settings.FontsBrowserProxy} */
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
index c7f4721a974..7f290fc3df3 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -110,7 +110,8 @@
embedded></cr-link-row>
<cr-link-row class="hr" label="$i18n{appearanceSettingsTitle}"
on-click="onAppearanceTap_"
- sub-label="$i18n{appearanceSettingsDescription}" embedded></cr-link-row>
+ sub-label="$i18n{appearanceSettingsDescription}"
+ external="[[isOSSettings_]]" embedded></cr-link-row>
<h2>$i18n{keyboardAndTextInputHeading}</h2>
<settings-toggle-button class="first"
@@ -142,7 +143,7 @@
<iron-collapse
opened="[[prefs.settings.a11y.switch_access.enabled.value]]">
<cr-link-row label="$i18n{switchAccessOptionsLabel}"
- on-click="onSwitchAccessSettingsTap_" embedded external>
+ on-click="onSwitchAccessSettingsTap_" embedded>
</cr-link-row>
</iron-collapse>
</template>
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
index 88238c3061f..5365829d90f 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
@@ -126,6 +126,18 @@ Polymer({
},
/**
+ * Whether this page shown as part of OS settings.
+ * TODO(crbug.com/986596): Remove this when SplitSettings is the default.
+ * @private
+ */
+ isOSSettings_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('isOSSettings');
+ },
+ },
+
+ /**
* |hasKeyboard_|starts undefined so observers don't trigger
* until it has been populated.
* @private
@@ -200,7 +212,7 @@ Polymer({
/** @private */
onSwitchAccessSettingsTap_: function() {
- chrome.send('showSwitchAccessSettings');
+ settings.navigateTo(settings.routes.MANAGE_SWITCH_ACCESS_SETTINGS);
},
/** @private */
@@ -212,9 +224,16 @@ Polymer({
/** @private */
onAppearanceTap_: function() {
- settings.navigateTo(
- settings.routes.APPEARANCE,
- /* dynamicParams */ null, /* removeSearch */ true);
+ if (loadTimeData.getBoolean('isOSSettings')) {
+ // Open browser appearance section in a new browser tab.
+ window.open('chrome://settings/appearance');
+ } else {
+ // Open browser appearance in this settings window.
+ // TODO(crbug.com/986596): Remove this when SplitSettings is the default.
+ settings.navigateTo(
+ settings.routes.APPEARANCE,
+ /* dynamicParams */ null, /* removeSearch */ true);
+ }
},
/** @private */
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.html b/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.html
index d8c101b1563..6134a743a50 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.html
@@ -6,6 +6,7 @@
<link rel="import" href="../controls/settings_slider.html">
<link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../i18n_setup.html">
+<link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-switch-access-subpage">
@@ -61,7 +62,23 @@
</div>
<settings-slider id="scanSpeedSlider" aria-describedby="scanSpeed"
pref="{{prefs.switch_access.auto_scan.speed_ms}}"
- ticks="[[autoScanSpeedValuesMs_]]"
+ ticks="[[autoScanSpeedRangeMs_]]"
+ min="[[minScanSpeedMs_]]"
+ max="[[maxScanSpeedMs_]]"
+ label-min="[[minScanSpeedLabelSec_]]"
+ label-max="[[maxScanSpeedLabelSec_]]">
+ </settings-dropdown-menu>
+ </div>
+ <div class="settings-box continuation list-item"
+ hidden$="[[!showKeyboardScanSettings_(
+ prefs.switch_access.auto_scan.enabled.value)]]">
+ <div class="start sub-item settings-box-text" id="keyboardScanSpeed">
+ $i18n{switchAccessAutoScanKeyboardSpeedLabel}
+ </div>
+ <settings-slider id="keyboardScanSpeedSlider"
+ aria-describedby="keyboardScanSpeed"
+ pref="{{prefs.switch_access.auto_scan.keyboard.speed_ms}}"
+ ticks="[[autoScanSpeedRangeMs_]]"
min="[[minScanSpeedMs_]]"
max="[[maxScanSpeedMs_]]"
label-min="[[minScanSpeedLabelSec_]]"
diff --git a/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.js b/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.js
index 328e60ca3d0..cd0026e9cdd 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/switch_access_subpage.js
@@ -3,6 +3,13 @@
// found in the LICENSE file.
/**
+ * @fileoverview 'switch-access-subpage' is the collapsible section containing
+ * Switch Access settings.
+ */
+
+(function() {
+
+/**
* Available switch assignment values.
* @enum {number}
* @const
@@ -13,14 +20,29 @@ const SwitchAccessAssignmentValue = {
ENTER: 2,
};
+/** @type {!Array<number>} */
+const AUTO_SCAN_SPEED_RANGE_MS = [
+ 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600,
+ 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800,
+ 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000
+];
+
/**
- * @fileoverview 'switch-access-subpage' is the collapsible section containing
- * Switch Access settings.
+ * @param {!Array<number>} ticksInMs
+ * @return {!Array<!cr_slider.SliderTick>}
*/
+function ticksWithLabelsInSec(ticksInMs) {
+ // Dividing by 1000 to convert milliseconds to seconds for the label.
+ return ticksInMs.map(x => ({label: `${x / 1000}`, value: x}));
+}
+
Polymer({
is: 'settings-switch-access-subpage',
- behaviors: [I18nBehavior],
+ behaviors: [
+ I18nBehavior,
+ PrefsBehavior,
+ ],
properties: {
/**
@@ -32,15 +54,10 @@ Polymer({
},
/** @private {Array<number>} */
- autoScanSpeedValuesMs_: {
+ autoScanSpeedRangeMs_: {
readOnly: true,
type: Array,
- value: [
- 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300,
- 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200,
- 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100,
- 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000
- ]
+ value: ticksWithLabelsInSec(AUTO_SCAN_SPEED_RANGE_MS),
},
/** @private {Object} */
@@ -123,6 +140,19 @@ Polymer({
},
/**
+ * @return {boolean} Whether to show settings for auto-scan within the
+ * keyboard.
+ * @private
+ */
+ showKeyboardScanSettings_: function() {
+ const improvedTextInputEnabled = loadTimeData.getBoolean(
+ 'showExperimentalAccessibilitySwitchAccessImprovedTextInput');
+ const autoScanEnabled = /** @type {boolean} */
+ (this.getPref('switch_access.auto_scan.enabled').value);
+ return improvedTextInputEnabled && autoScanEnabled;
+ },
+
+ /**
* @param {string} command
*/
onSwitchAssigned_: function(command) {
@@ -166,3 +196,4 @@ Polymer({
'durationInSeconds', this.formatter_.format(scanSpeedValueSec));
},
});
+})();
diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page.html b/chromium/chrome/browser/resources/settings/about_page/about_page.html
index 18c371cdbbe..99c0a1c19a1 100644
--- a/chromium/chrome/browser/resources/settings/about_page/about_page.html
+++ b/chromium/chrome/browser/resources/settings/about_page/about_page.html
@@ -23,6 +23,7 @@
<if expr="chromeos">
<link rel="import" href="detailed_build_info.html">
<link rel="import" href="update_warning_dialog.html">
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../settings_page/settings_subpage.html">
<link rel="import" href="../reset_page/powerwash_dialog.html">
</if>
@@ -150,14 +151,19 @@
</span>
</if>
<if expr="chromeos">
- <div id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]">
- $i18n{endOfLifeMessage}
- <a href="$i18n{endOfLifeLearnMoreURL}" target="_blank">
- $i18n{learnMore}
- </a>
- </div>
+ <div id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]">
+ $i18n{endOfLifeMessage}
+ <a href="$i18n{endOfLifeLearnMoreURL}" target="_blank">
+ $i18n{learnMore}
+ </a>
+ </div>
</if>
<div class="secondary">$i18n{aboutBrowserVersion}</div>
+<if expr="chromeos">
+ <div class="secondary"
+ inner-h-t-m-l="[[getUpdateOsSettingsLink_()]]">
+ </div>
+</if>
</div>
<div class="separator" hidden="[[!showButtonContainer_]]"></div>
<span id="buttonContainer" hidden="[[!showButtonContainer_]]">
@@ -233,7 +239,7 @@
<if expr="_google_chrome">
<cr-link-row class="hr" id="reportIssue" on-click="onReportIssueTap_"
hidden="[[!prefs.feedback_allowed.value]]"
- label="$i18n{aboutReportAnIssue}"></cr-link-row>
+ label="$i18n{aboutReportAnIssue}" external></cr-link-row>
</if>
<if expr="chromeos">
<cr-link-row class="hr" id="detailed-build-info-trigger"
diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page.js b/chromium/chrome/browser/resources/settings/about_page/about_page.js
index 4899236f7b7..d4781a4d1b7 100644
--- a/chromium/chrome/browser/resources/settings/about_page/about_page.js
+++ b/chromium/chrome/browser/resources/settings/about_page/about_page.js
@@ -491,7 +491,7 @@ Polymer({
// If Chrome OS has reached end of life, display a special icon and
// ignore UpdateStatus.
if (this.hasEndOfLife_) {
- return 'settings:end-of-life';
+ return 'os-settings:end-of-life';
}
// </if>
@@ -632,6 +632,20 @@ Polymer({
this.i18nAdvanced('aboutProductOsLicense');
},
+ // <if expr="chromeos">
+ /**
+ * @return {string}
+ * @private
+ */
+ getUpdateOsSettingsLink_: function() {
+ // Note: This string contains raw HTML and thus requires i18nAdvanced().
+ // Since the i18n template syntax (e.g., $i18n{}) does not include an
+ // "advanced" version, it's not possible to inline this link directly in the
+ // HTML.
+ return this.i18nAdvanced('aboutUpdateOsSettingsLink');
+ },
+ // </if>
+
/**
* @param {boolean} enabled True if Crostini is enabled.
* @private
diff --git a/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.html b/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.html
deleted file mode 100644
index cab1b4a924f..00000000000
--- a/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="../open_window_proxy.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
-
-<dom-module id="settings-app-management-page">
- <template>
- <cr-link-row id="appManagementButton"
- label="$i18n{manageYourApps}" sub-label="$i18n{manageYourAppsSublabel}"
- on-click="openAppManagement_" external>
- </cr-link-row>
- </template>
- <script src="app_management_page.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.js b/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.js
deleted file mode 100644
index da525757d79..00000000000
--- a/chromium/chrome/browser/resources/settings/app_management_page/app_management_page.js
+++ /dev/null
@@ -1,19 +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
- * 'app-management-page' is the settings page which links to App Management.
- */
-
-Polymer({
- is: 'settings-app-management-page',
-
- /** @private */
- openAppManagement_: function() {
- chrome.metricsPrivate.recordUserAction('SettingsPage.OpenAppManagement');
- settings.OpenWindowProxyImpl.getInstance().openURL(
- 'chrome://app-management');
- },
-});
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/BUILD.gn b/chromium/chrome/browser/resources/settings/appearance_page/BUILD.gn
index 7b27f61c697..a3c3d26c232 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/appearance_page/BUILD.gn
@@ -12,6 +12,10 @@ js_type_check("closure_compile") {
":fonts_browser_proxy",
":home_url_input",
]
+
+ if (is_chromeos) {
+ deps += [ ":wallpaper_browser_proxy" ]
+ }
}
js_library("appearance_fonts_page") {
@@ -42,6 +46,7 @@ js_library("appearance_browser_proxy") {
js_library("appearance_page") {
deps = [
":appearance_browser_proxy",
+ ":wallpaper_browser_proxy",
"..:page_visibility",
"..:route",
"../controls:settings_dropdown_menu",
@@ -75,3 +80,10 @@ js_library("home_url_input") {
]
externs_list = [ "$externs_path/settings_private.js" ]
}
+
+js_library("wallpaper_browser_proxy") {
+ deps = [
+ "//ui/webui/resources/js:cr",
+ ]
+ externs_list = [ "$externs_path/chrome_send.js" ]
+}
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js b/chromium/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js
index c75464dc66e..7e8bd802fc3 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_browser_proxy.js
@@ -17,22 +17,6 @@ cr.define('settings', function() {
/** @return {boolean} Whether the current profile is supervised. */
isSupervised() {}
- /**
- * @return {!Promise<boolean>} Whether the wallpaper setting row should be
- * visible.
- */
- isWallpaperSettingVisible() {}
-
- /**
- * @return {!Promise<boolean>} Whether the wallpaper is policy controlled.
- */
- isWallpaperPolicyControlled() {}
-
- // <if expr="chromeos">
- openWallpaperManager() {}
-
- // </if>
-
useDefaultTheme() {}
// <if expr="is_linux and not chromeos">
@@ -70,24 +54,6 @@ cr.define('settings', function() {
return loadTimeData.getBoolean('isSupervised');
}
- // <if expr="chromeos">
- /** @override */
- isWallpaperSettingVisible() {
- return cr.sendWithPromise('isWallpaperSettingVisible');
- }
-
- /** @override */
- isWallpaperPolicyControlled() {
- return cr.sendWithPromise('isWallpaperPolicyControlled');
- }
-
- /** @override */
- openWallpaperManager() {
- chrome.send('openWallpaperManager');
- }
-
- // </if>
-
/** @override */
useDefaultTheme() {
chrome.send('useDefaultTheme');
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
index df9863a3a64..3a619511bed 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -18,6 +18,10 @@
<link rel="import" href="appearance_fonts_page.html">
<link rel="import" href="home_url_input.html">
+<if expr="chromeos">
+<link rel="import" href="../appearance_page/wallpaper_browser_proxy.html">
+</if>
+
<dom-module id="settings-appearance-page">
<template>
<style include="settings-shared md-select iron-flex">
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
index 9fa3b60a182..2551cf3b191 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -119,7 +119,12 @@ Polymer({
},
/** @private {?settings.AppearanceBrowserProxy} */
- browserProxy_: null,
+ appearanceBrowserProxy_: null,
+
+ // <if expr="chromeos">
+ /** @private {?settings.WallpaperBrowserProxy} */
+ wallpaperBrowserProxy_: null,
+ // </if>
observers: [
'defaultFontSizeChanged_(prefs.webkit.webprefs.default_font_size.value)',
@@ -133,7 +138,12 @@ Polymer({
/** @override */
created: function() {
- this.browserProxy_ = settings.AppearanceBrowserProxyImpl.getInstance();
+ this.appearanceBrowserProxy_ =
+ settings.AppearanceBrowserProxyImpl.getInstance();
+ // <if expr="chromeos">
+ this.wallpaperBrowserProxy_ =
+ settings.WallpaperBrowserProxyImpl.getInstance();
+ // </if>
},
/** @override */
@@ -141,16 +151,16 @@ Polymer({
this.$.defaultFontSize.menuOptions = this.fontSizeOptions_;
// TODO(dschuyler): Look into adding a listener for the
// default zoom percent.
- this.browserProxy_.getDefaultZoom().then(zoom => {
+ this.appearanceBrowserProxy_.getDefaultZoom().then(zoom => {
this.defaultZoom_ = zoom;
});
// <if expr="chromeos">
- this.browserProxy_.isWallpaperSettingVisible().then(
+ this.wallpaperBrowserProxy_.isWallpaperSettingVisible().then(
isWallpaperSettingVisible => {
assert(this.pageVisibility);
this.pageVisibility.setWallpaper = isWallpaperSettingVisible;
});
- this.browserProxy_.isWallpaperPolicyControlled().then(
+ this.wallpaperBrowserProxy_.isWallpaperPolicyControlled().then(
isPolicyControlled => {
this.isWallpaperPolicyControlled_ = isPolicyControlled;
});
@@ -219,13 +229,13 @@ Polymer({
* @private
*/
openWallpaperManager_: function() {
- this.browserProxy_.openWallpaperManager();
+ this.wallpaperBrowserProxy_.openWallpaperManager();
},
// </if>
/** @private */
onUseDefaultTap_: function() {
- this.browserProxy_.useDefaultTheme();
+ this.appearanceBrowserProxy_.useDefaultTheme();
},
// <if expr="is_linux and not chromeos">
@@ -254,7 +264,8 @@ Polymer({
* @private
*/
showUseSystem_: function(themeId, useSystemTheme) {
- return (!!themeId || !useSystemTheme) && !this.browserProxy_.isSupervised();
+ return (!!themeId || !useSystemTheme) &&
+ !this.appearanceBrowserProxy_.isSupervised();
},
/**
@@ -271,7 +282,7 @@ Polymer({
/** @private */
onUseSystemTap_: function() {
- this.browserProxy_.useSystemTheme();
+ this.appearanceBrowserProxy_.useSystemTheme();
},
// </if>
@@ -288,7 +299,7 @@ Polymer({
if (themeId.length > 0 && themeId != AUTOGENERATED_THEME_ID) {
assert(!useSystemTheme);
- this.browserProxy_.getThemeInfo(themeId).then(info => {
+ this.appearanceBrowserProxy_.getThemeInfo(themeId).then(info => {
this.themeSublabel_ = info.name;
});
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.html b/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.html
new file mode 100644
index 00000000000..59b04eed214
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.html
@@ -0,0 +1,2 @@
+<link rel="href" src="chrome://resources/html/cr.html">
+<script src="wallpaper_browser_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.js b/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.js
new file mode 100644
index 00000000000..90a2e4db7d9
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/appearance_page/wallpaper_browser_proxy.js
@@ -0,0 +1,48 @@
+// 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('settings', function() {
+ /** @interface */
+ class WallpaperBrowserProxy {
+ /**
+ * @return {!Promise<boolean>} Whether the wallpaper setting row should be
+ * visible.
+ */
+ isWallpaperSettingVisible() {}
+
+ /**
+ * @return {!Promise<boolean>} Whether the wallpaper is policy controlled.
+ */
+ isWallpaperPolicyControlled() {}
+
+ openWallpaperManager() {}
+ }
+
+ /**
+ * @implements {settings.WallpaperBrowserProxy}
+ */
+ class WallpaperBrowserProxyImpl {
+ /** @override */
+ isWallpaperSettingVisible() {
+ return cr.sendWithPromise('isWallpaperSettingVisible');
+ }
+
+ /** @override */
+ isWallpaperPolicyControlled() {
+ return cr.sendWithPromise('isWallpaperPolicyControlled');
+ }
+
+ /** @override */
+ openWallpaperManager() {
+ chrome.send('openWallpaperManager');
+ }
+ }
+
+ cr.addSingletonGetter(WallpaperBrowserProxyImpl);
+
+ return {
+ WallpaperBrowserProxy: WallpaperBrowserProxy,
+ WallpaperBrowserProxyImpl: WallpaperBrowserProxyImpl,
+ };
+});
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn
index 84a9f949cac..1afa9c4b7ef 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn
@@ -117,14 +117,16 @@ js_library("passwords_section") {
":password_list_item",
":password_manager_proxy",
"..:global_scroll_target_behavior",
+ "../people_page:sync_browser_proxy",
"//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
"//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
"//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
- "//ui/webui/resources/cr_elements/cr_toast:cr_toast",
+ "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:list_property_update_behavior",
"//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:web_ui_listener_behavior",
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
externs_list = [ "$externs_path/passwords_private.js" ]
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html
index 1e7b7923b1a..58e376e7433 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html
+++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -3,7 +3,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast_manager.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
@@ -17,6 +17,7 @@
<link rel="import" href="../controls/extension_controlled_indicator.html">
<link rel="import" href="../global_scroll_target_behavior.html">
<link rel="import" href="../prefs/prefs.html">
+<link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../settings_shared_css.html">
<link rel="import" href="../site_favicon.html">
<link rel="import" href="password_edit_dialog.html">
@@ -72,12 +73,23 @@
</extension-controlled-indicator>
</div>
</template>
+ <settings-toggle-button id="passwordsLeakDetectionCheckbox"
+ pref="{{prefs.profile.password_manager_leak_detection}}"
+ checked="[[getCheckedLeakDetection_(
+ userSignedIn_, prefs.profile.password_manager_leak_detection)]]"
+ label="$i18n{passwordsLeakDetectionLabel}"
+ sub-label="[[getPasswordsLeakDetectionSubLabel_(
+ userSignedIn_, prefs.profile.password_manager_leak_detection)]]"
+ hidden$="[[!passwordsLeakDetectionEnabled_]]"
+ disabled="[[!userSignedIn_]]">
+ </settings-toggle-button>
<settings-toggle-button id="autosigninCheckbox"
pref="{{prefs.credentials_enable_autosignin}}"
label="$i18n{passwordsAutosigninLabel}"
sub-label="$i18n{passwordsAutosigninDescription}">
</settings-toggle-button>
- <div id="manageLink" class="settings-box first two-line">
+ <div id="manageLink" class="settings-box first two-line"
+ hidden$="[[hidePasswordsLink_]]">
<!-- This span lays out the url correctly, relative to the label. -->
<span>$i18nRaw{managePasswordsLabel}</span>
</div>
@@ -163,12 +175,11 @@
</settings-password-prompt-dialog>
</template>
</if>
- <cr-toast id="undoToast" duration="[[toastDuration_]]">
- <div id="undoLabel">$i18n{passwordDeleted}</div>
- <cr-button on-click="onUndoButtonTap_">
- $i18n{undoRemovePassword}
- </cr-button>
- </cr-toast>
+ <cr-toast-manager on-undo-click="onUndoButtonTap_"
+ undo-label="$i18n{undoRemovePassword}"
+ undo-description="$i18n{undoDescription}"
+ duration="[[toastDuration_]]">
+ </cr-toast-manager>
<div class="settings-box block first">
<h2>$i18n{passwordExceptionsHeading}</h2>
</div>
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js
index 1f552fdf4ec..a98d69646d4 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js
+++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -36,9 +36,11 @@ Polymer({
behaviors: [
I18nBehavior,
+ WebUIListenerBehavior,
ListPropertyUpdateBehavior,
Polymer.IronA11yKeysBehavior,
settings.GlobalScrollTargetBehavior,
+ PrefsBehavior,
],
properties: {
@@ -94,6 +96,18 @@ Polymer({
},
/** @private */
+ hidePasswordsLink_: {
+ type: Boolean,
+ computed: 'computeHidePasswordsLink_(syncPrefs_, syncStatus_)',
+ },
+
+ /** @private */
+ passwordsLeakDetectionEnabled_: {
+ type: Boolean,
+ value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'),
+ },
+
+ /** @private */
showExportPasswords_: {
type: Boolean,
computed: 'hasPasswords_(savedPasswords.splices)',
@@ -111,6 +125,23 @@ Polymer({
/** @private */
showPasswordEditDialog_: Boolean,
+ // <if expr="not chromeos">
+ /** @private {Array<!settings.StoredAccount>} */
+ storedAccounts_: Object,
+ // </if>
+
+ /** @private {settings.SyncPrefs} */
+ syncPrefs_: Object,
+
+ /** @private {settings.SyncStatus} */
+ syncStatus_: Object,
+
+ /** @private */
+ userSignedIn_: {
+ type: Boolean,
+ computed: 'computeUserSignedIn_(syncStatus_, storedAccounts_)',
+ },
+
/** Filter on the saved passwords and exceptions. */
filter: {
type: String,
@@ -156,11 +187,14 @@ Polymer({
},
/**
- * The element to return focus to, when the currently active dialog is
- * closed.
- * @private {?HTMLElement}
+ * A stack of the elements that triggered dialog to open and should therefore
+ * receive focus when that dialog is closed. The bottom of the stack is the
+ * element that triggered the earliest open dialog and top of the stack is the
+ * element that triggered the most recent (i.e. active) dialog. If no dialog
+ * is open, the stack is empty.
+ * @private {!Array<Element>}
*/
- activeDialogAnchor_: null,
+ activeDialogAnchorStack_: [],
/**
* @type {PasswordManagerProxy}
@@ -210,7 +244,7 @@ Polymer({
this.tokenRequestManager_ = new settings.BlockingRequestManager();
} else {
this.tokenRequestManager_ = new settings.BlockingRequestManager(
- () => this.showPasswordPromptDialog_ = true);
+ this.openPasswordPromptDialog_.bind(this));
}
// </if>
@@ -226,6 +260,23 @@ Polymer({
this.notifySplices('savedPasswords', []);
+ const syncBrowserProxy = settings.SyncBrowserProxyImpl.getInstance();
+
+ const syncStatusChanged = syncStatus => this.syncStatus_ = syncStatus;
+ syncBrowserProxy.getSyncStatus().then(syncStatusChanged);
+ this.addWebUIListener('sync-status-changed', syncStatusChanged);
+
+ // <if expr="not chromeos">
+ const storedAccountsChanged = storedAccounts => this.storedAccounts_ =
+ storedAccounts;
+ syncBrowserProxy.getStoredAccounts().then(storedAccountsChanged);
+ this.addWebUIListener('stored-accounts-updated', storedAccountsChanged);
+ // </if>
+
+ const syncPrefsChanged = syncPrefs => this.syncPrefs_ = syncPrefs;
+ syncBrowserProxy.sendSyncPrefsChanged();
+ this.addWebUIListener('sync-prefs-changed', syncPrefsChanged);
+
Polymer.RenderStatus.afterNextRender(this, function() {
Polymer.IronA11yAnnouncer.requestAvailability();
});
@@ -243,9 +294,8 @@ Polymer({
* @type {function(!Array<PasswordManagerProxy.ExceptionEntry>):void}
*/
(this.setPasswordExceptionsListener_));
-
- if (this.$.undoToast.open) {
- this.$.undoToast.hide();
+ if (cr.toastManager.getInstance().isToastOpen) {
+ cr.toastManager.getInstance().hide();
}
},
@@ -273,6 +323,12 @@ Polymer({
onPasswordPromptClosed_: function() {
this.showPasswordPromptDialog_ = false;
+ cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop()));
+ },
+
+ openPasswordPromptDialog_: function() {
+ this.activeDialogAnchorStack_.push(getDeepActiveElement());
+ this.showPasswordPromptDialog_ = true;
},
// </if>
@@ -290,8 +346,7 @@ Polymer({
/** @private */
onPasswordEditDialogClosed_: function() {
this.showPasswordEditDialog_ = false;
- cr.ui.focusWithoutInk(assert(this.activeDialogAnchor_));
- this.activeDialogAnchor_ = null;
+ cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop()));
// Trigger a re-evaluation of the activePassword as the visibility state of
// the password might have changed.
@@ -299,6 +354,33 @@ Polymer({
},
/**
+ * @return {boolean}
+ * @private
+ */
+ computeHidePasswordsLink_: function() {
+ return !!this.syncStatus_ && !!this.syncStatus_.signedIn &&
+ !!this.syncPrefs_ && !!this.syncPrefs_.encryptAllData;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ computeUserSignedIn_: function() {
+ return (!!this.syncStatus_ && !!this.syncStatus_.signedIn) ||
+ (!!this.storedAccounts_ && this.storedAccounts_.length > 0);
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ getCheckedLeakDetection_: function() {
+ return this.userSignedIn_ &&
+ !!this.getPref('profile.password_manager_leak_detection').value;
+ },
+
+ /**
* @param {string} filter
* @return {!Array<!PasswordManagerProxy.UiEntryWithPassword>}
* @private
@@ -314,6 +396,20 @@ Polymer({
},
/**
+ * @return {string}
+ * @private
+ */
+ getPasswordsLeakDetectionSubLabel_: function() {
+ if (this.userSignedIn_) {
+ return this.i18n('passwordsLeakDetectionSignedInDescription');
+ }
+ if (this.getPref('profile.password_manager_leak_detection').value) {
+ return this.i18n('passwordsLeakDetectionSignedOutEnabledDescription');
+ }
+ return this.i18n('passwordsLeakDetectionSignedOutDisabledDescription');
+ },
+
+ /**
* @param {string} filter
* @return {function(!chrome.passwordsPrivate.ExceptionEntry): boolean}
* @private
@@ -330,8 +426,7 @@ Polymer({
onMenuRemovePasswordTap_: function() {
this.passwordManager_.removeSavedPassword(
this.activePassword.item.entry.id);
- this.fire('iron-announce', {text: this.$.undoLabel.textContent});
- this.$.undoToast.show();
+ cr.toastManager.getInstance().show(this.i18n('passwordDeleted'), false);
/** @type {CrActionMenuElement} */ (this.$.menu).close();
},
@@ -344,7 +439,7 @@ Polymer({
const activeElement = getDeepActiveElement();
if (!activeElement || !isEditable(activeElement)) {
this.passwordManager_.undoRemoveSavedPasswordOrException();
- this.$.undoToast.hide();
+ cr.toastManager.getInstance().hide();
// Preventing the default is necessary to not conflict with a possible
// search action.
event.preventDefault();
@@ -353,7 +448,7 @@ Polymer({
onUndoButtonTap_: function() {
this.passwordManager_.undoRemoveSavedPasswordOrException();
- this.$.undoToast.hide();
+ cr.toastManager.getInstance().hide();
},
/**
* Fires an event that should delete the password exception.
@@ -376,7 +471,7 @@ Polymer({
this.activePassword =
/** @type {!PasswordListItemElement} */ (event.detail.listItem);
menu.showAt(target);
- this.activeDialogAnchor_ = target;
+ this.activeDialogAnchorStack_.push(target);
},
/**
@@ -389,7 +484,7 @@ Polymer({
/** @type {!HTMLElement} */ (this.$$('#exportImportMenuButton'));
menu.showAt(target);
- this.activeDialogAnchor_ = target;
+ this.activeDialogAnchorStack_.push(target);
},
/**
@@ -413,8 +508,7 @@ Polymer({
/** @private */
onPasswordsExportDialogClosed_: function() {
this.showPasswordsExportDialog_ = false;
- cr.ui.focusWithoutInk(assert(this.activeDialogAnchor_));
- this.activeDialogAnchor_ = null;
+ cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop()));
},
/**
diff --git a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
index 3680ef7085f..ab89a35dd33 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -18,6 +18,7 @@ js_library("basic_page") {
"../android_apps_page:android_apps_browser_proxy",
"../change_password_page:change_password_browser_proxy",
"../chrome_cleanup_page:chrome_cleanup_proxy",
+ "../prefs:prefs_behavior",
"../settings_page:main_page_behavior",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:web_ui_listener_behavior",
diff --git a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
index 80d61cd92c3..46deb873d7d 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -17,7 +17,7 @@
<link rel="import" href="../settings_page_css.html">
<if expr="chromeos">
-<link rel="import" href="../app_management_page/app_management_page.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="../android_apps_page/android_apps_browser_proxy.html">
<link rel="import" href="../android_apps_page/android_apps_page.html">
<link rel="import" href="../bluetooth_page/bluetooth_page.html">
@@ -26,6 +26,7 @@
<link rel="import" href="../device_page/device_page.html">
<link rel="import" href="../internet_page/internet_page.html">
<link rel="import" href="../multidevice_page/multidevice_page.html">
+<link rel="import" href="../prefs/prefs_behavior.html">
</if>
<if expr="not chromeos">
@@ -36,7 +37,7 @@
includes both the basic and advanced settings. -->
<dom-module id="settings-basic-page">
<template>
- <style include="settings-page-styles cr-hidden-style">
+ <style include="settings-page-styles cr-hidden-style settings-shared">
:host([is-subpage-animating]) {
/* Prevent an unwanted horizontal scrollbar when transitioning back from
* a sub-page. */
@@ -62,13 +63,14 @@
font-weight: 600;
}
+ #osSettingsBanner,
#secondaryUserBanner {
@apply --cr-card-elevation;
align-items: center;
background-color: white;
border-radius: 2px;
display: flex;
- margin: 21px 0;
+ margin-top: 21px;
}
#secondaryUserIcon {
@@ -85,11 +87,14 @@
#toggleContainer {
align-items: center;
+ color: var(--cr-primary-text-color);
display: flex;
font: inherit;
justify-content: center;
margin-bottom: 0;
margin-top: 0;
+ padding-bottom: 0;
+ padding-top: 0;
}
#toggleSpacer {
@@ -108,12 +113,22 @@
</settings-reset-profile-banner>
</template>
<if expr="chromeos">
+ <template is="dom-if" if="[[showOSSettingsBanner_]]">
+ <div id="osSettingsBanner" class="settings-box">
+ <div class="start" on-click="onOSSettingsBannerClick_">
+ $i18nRaw{osSettingsBannerText}
+ </div>
+ <cr-icon-button class="icon-clear"
+ id="hideOSSettings"
+ aria-label="$i18n{clear}"
+ on-click="onOSSettingsBannerClosed_">
+ </cr-icon-button>
+ </div>
+ </template>
<div id="secondaryUserBanner" hidden="[[!showSecondaryUserBanner_]]">
<div id="secondaryUserIcon"></div>
<div class="flex">$i18n{secondaryUserBannerText}</div>
</div>
-</if>
-<if expr="chromeos">
<template is="dom-if" if="[[showPage_(pageVisibility.internet)]]"
restamp>
<settings-section page-title="$i18n{internetPageTitle}"
@@ -180,21 +195,12 @@
</settings-section>
</template>
</if>
- <template is="dom-if" if="[[showPage_(pageVisibility.search)]]" restamp>
- <settings-section page-title="$i18n{searchPageTitle}"
- section="search">
- <settings-search-page prefs="{{prefs}}"></settings-search-page>
- </settings-section>
- </template>
+ <settings-section page-title="$i18n{searchPageTitle}"
+ section="search">
+ <settings-search-page prefs="{{prefs}}"></settings-search-page>
+ </settings-section>
<if expr="chromeos">
- <template is="dom-if" if="[[showApps]]" restamp>
- <settings-section page-title="$i18n{appsPageTitle}" section="apps">
- <settings-app-management-page>
- </settings-app-management-page>
- </settings-section>
- </template>
- <template is="dom-if" if="[[shouldCreateAndroidAppsSection_(
- showAndroidApps, pageVisibility)]]" restamp>
+ <template is="dom-if" if="[[showAndroidApps]]" restamp>
<settings-section page-title="$i18n{androidAppsPageTitle}"
section="androidApps" hidden$="[[!shouldShowAndroidAppsSection_(
androidAppsInfo)]]">
@@ -314,13 +320,10 @@
</settings-section>
</template>
<if expr="not chromeos">
- <template is="dom-if" if="[[showPage_(pageVisibility.system)]]"
- restamp>
- <settings-section page-title="$i18n{systemPageTitle}"
- section="system">
- <settings-system-page prefs="{{prefs}}"></settings-system-page>
- </settings-section>
- </template>
+ <settings-section page-title="$i18n{systemPageTitle}"
+ section="system">
+ <settings-system-page prefs="{{prefs}}"></settings-system-page>
+ </settings-section>
</if>
<template is="dom-if" if="[[showPage_(pageVisibility.reset)]]"
restamp>
diff --git a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
index 53f94adc713..f2f0131a77c 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -6,12 +6,33 @@
* @fileoverview
* 'settings-basic-page' is the settings page containing the actual settings.
*/
+(function() {
+'use strict';
+
+// <if expr="chromeos">
+const OS_BANNER_INTERACTION_METRIC_NAME =
+ 'ChromeOS.Settings.OsBannerInteraction';
+
+/**
+ * These values are persisted to logs and should not be renumbered or re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+const CrosSettingsOsBannerInteraction = {
+ NotShown: 0,
+ Shown: 1,
+ Clicked: 2,
+ Closed: 3,
+};
+// </if>
+
Polymer({
is: 'settings-basic-page',
behaviors: [
settings.MainPageBehavior,
settings.RouteObserverBehavior,
+ PrefsBehavior,
WebUIListenerBehavior,
],
@@ -23,8 +44,6 @@ Polymer({
},
// <if expr="chromeos">
- showApps: Boolean,
-
showAndroidApps: Boolean,
showCrostini: Boolean,
@@ -91,6 +110,13 @@ Polymer({
type: Boolean,
computed: 'computeShowSecondaryUserBanner_(hasExpandedSection_)',
},
+
+ /** @private */
+ showOSSettingsBanner_: {
+ type: Boolean,
+ computed: 'computeShowOSSettingsBanner_(' +
+ 'prefs.settings.cros.show_os_banner.value, currentRoute_)',
+ },
// </if>
/** @private {!settings.Route|undefined} */
@@ -111,6 +137,11 @@ Polymer({
*/
advancedTogglingInProgress_: false,
+ // <if expr="chromeos">
+ /** @private {boolean} */
+ osBannerShowMetricRecorded_: false,
+ // </if>
+
/** @override */
attached: function() {
this.currentRoute_ = settings.getCurrentRoute();
@@ -220,6 +251,58 @@ Polymer({
return !this.hasExpandedSection_ &&
loadTimeData.getBoolean('isSecondaryUser');
},
+
+ /**
+ * @return {boolean|undefined}
+ * @private
+ */
+ computeShowOSSettingsBanner_: function() {
+ // this.prefs is implicitly used by this.getPref() below.
+ if (!this.prefs || !this.currentRoute_) {
+ return;
+ }
+ // Don't show the banner when SplitSettings is disabled (and hence this page
+ // is already showing OS settings).
+ if (loadTimeData.getBoolean('showOSSettings')) {
+ return false;
+ }
+ const showPref = /** @type {boolean} */ (
+ this.getPref('settings.cros.show_os_banner').value);
+
+ // Banner only shows on the main page because direct navigations to a
+ // sub-page are unlikely to be due to a user looking for an OS setting.
+ const show = showPref && !this.currentRoute_.isSubpage();
+
+ // Record the show metric once. We can't record the metric in attached()
+ // because prefs might not be ready yet.
+ if (!this.osBannerShowMetricRecorded_) {
+ chrome.metricsPrivate.recordEnumerationValue(
+ OS_BANNER_INTERACTION_METRIC_NAME,
+ show ? CrosSettingsOsBannerInteraction.Shown :
+ CrosSettingsOsBannerInteraction.NotShown,
+ Object.keys(CrosSettingsOsBannerInteraction).length);
+ this.osBannerShowMetricRecorded_ = true;
+ }
+ return show;
+ },
+
+ /** @private */
+ onOSSettingsBannerClick_: function() {
+ // The label has a link that opens the page, so just record the metric.
+ chrome.metricsPrivate.recordEnumerationValue(
+ OS_BANNER_INTERACTION_METRIC_NAME,
+ CrosSettingsOsBannerInteraction.Clicked,
+ Object.keys(CrosSettingsOsBannerInteraction).length);
+ },
+
+ /** @private */
+ onOSSettingsBannerClosed_: function() {
+ this.setPrefValue('settings.cros.show_os_banner', false);
+ chrome.metricsPrivate.recordEnumerationValue(
+ OS_BANNER_INTERACTION_METRIC_NAME,
+ CrosSettingsOsBannerInteraction.Closed,
+ Object.keys(CrosSettingsOsBannerInteraction).length);
+ },
// </if>
/** @private */
@@ -236,18 +319,6 @@ Polymer({
},
/**
- * Returns true in case Android apps settings needs to be created. It is not
- * created in case ARC++ is not allowed for the current profile.
- * @return {boolean}
- * @private
- */
- shouldCreateAndroidAppsSection_: function() {
- const visibility = /** @type {boolean|undefined} */ (
- this.get('pageVisibility.androidApps'));
- return this.showAndroidApps && this.showPage_(visibility);
- },
-
- /**
* Returns true in case Android apps settings should be shown. It is not
* shown in case we don't have the Play Store app and settings app is not
* yet available.
@@ -382,3 +453,4 @@ Polymer({
return bool.toString();
},
});
+})();
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
index bf85b1f8556..739b1b7b29b 100644
--- a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.html
@@ -5,6 +5,7 @@
<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">
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../icons.html">
<link rel="import" href="../settings_shared_css.html">
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
index ead6fe1075e..9ed885e2782 100644
--- a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_device_list_item.js
@@ -132,24 +132,24 @@ Polymer({
case 'computer':
return 'cr:computer';
case 'phone':
- return 'settings:smartphone';
+ return 'os-settings:smartphone';
case 'audio':
case 'carAudio':
- return 'settings:headset';
+ return 'os-settings:headset';
case 'video':
return 'cr:videocam';
case 'joystick':
case 'gamepad':
- return 'settings:gamepad';
+ return 'os-settings:gamepad';
case 'keyboard':
case 'keyboardMouseCombo':
- return 'settings:keyboard';
+ return 'os-settings:keyboard';
case 'tablet':
- return 'settings:tablet';
+ return 'os-settings:tablet';
case 'mouse':
- return 'settings:mouse';
+ return 'os-settings:mouse';
default:
- return device.connected ? 'settings:bluetooth-connected' :
+ return device.connected ? 'os-settings:bluetooth-connected' :
'cr:bluetooth';
}
},
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
index 81f28b1245d..44dac770e3e 100644
--- a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -5,8 +5,8 @@
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../i18n_setup.html">
-<link rel="import" href="../icons.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../settings_page/settings_animated_pages.html">
diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
index b84118487a0..fd9aabbdf7f 100644
--- a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
+++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
@@ -172,7 +172,7 @@ Polymer({
// Don't use |this.bluetoothToggleState_| here, since it has not been
// updated yet to the latest value.
if (!bluetoothToggleState) {
- return 'settings:bluetooth-disabled';
+ return 'os-settings:bluetooth-disabled';
}
return 'cr:bluetooth';
},
diff --git a/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn
index e2642b28c73..37366df42de 100644
--- a/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -28,6 +28,13 @@ if (optimize_webui) {
"crisper.js",
"lazy_load.crisper.js",
]
+ excludes = [
+ "chrome://os-settings/app-management/app_management.mojom-lite.js",
+ "chrome://os-settings/app-management/bitmap.mojom-lite.js",
+ "chrome://os-settings/app-management/image_info.mojom-lite.js",
+ "chrome://os-settings/app-management/image.mojom-lite.js",
+ "chrome://os-settings/app-management/types.mojom-lite.js",
+ ]
deps = [
":unpak",
@@ -63,6 +70,7 @@ if (optimize_webui) {
group("closure_compile") {
deps = [
"os_a11y_page:closure_compile",
+ "os_apps_page:closure_compile",
"os_files_page:closure_compile",
"os_languages_page:closure_compile",
"os_people_page:closure_compile",
diff --git a/chromium/chrome/browser/resources/settings/app_management_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
index d404c63c107..b54af0ac04f 100644
--- a/chromium/chrome/browser/resources/settings/app_management_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
@@ -6,13 +6,16 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
- ":app_management_page",
+ ":os_apps_page",
]
}
-js_library("app_management_page") {
+js_library("os_apps_page") {
deps = [
- "..:open_window_proxy",
+ "../../:route",
+ "../../settings_page:settings_animated_pages",
+ "app_management_page",
]
+
externs_list = [ "$externs_path/metrics_private.js" ]
}
diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
new file mode 100644
index 00000000000..c9841d1a9d7
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -0,0 +1,230 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":actions",
+ ":api_listener",
+ ":app_item",
+ ":app_management_page",
+ ":app_permission_view",
+ ":arc_permission_view",
+ ":browser_proxy",
+ ":chrome_app_permission_view",
+ ":constants",
+ ":dom_switch",
+ ":fake_page_handler",
+ ":main_view",
+ ":permission_item",
+ ":permission_toggle",
+ ":pin_to_shelf_item",
+ ":pwa_permission_view",
+ ":reducers",
+ ":router",
+ ":store",
+ ":store_client",
+ ":toggle_row",
+ ":types",
+ ":uninstall_button",
+ ":util",
+ ]
+}
+
+js_library("actions") {
+ deps = [
+ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
+js_library("api_listener") {
+ deps = [
+ ":actions",
+ ":store",
+ ":util",
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
+js_library("app_item") {
+ deps = [
+ ":actions",
+ ":store_client",
+ "//ui/webui/resources/js:load_time_data",
+ ]
+}
+
+js_library("app_management_page") {
+ deps = [
+ ":actions",
+ ":browser_proxy",
+ ":main_view",
+ ":router",
+ ":store",
+ ":store_client",
+ ]
+}
+
+js_library("app_permission_view") {
+ deps = [
+ ":arc_permission_view",
+ ":chrome_app_permission_view",
+ ":dom_switch",
+ ":pwa_permission_view",
+ ":store_client",
+ ]
+}
+
+js_library("arc_permission_view") {
+ deps = [
+ ":constants",
+ ":fake_page_handler",
+ ":permission_item",
+ ":pin_to_shelf_item",
+ ":store_client",
+ ]
+}
+
+js_library("browser_proxy") {
+ deps = [
+ ":fake_page_handler",
+ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
+js_library("chrome_app_permission_view") {
+ deps = [
+ ":fake_page_handler",
+ ":pin_to_shelf_item",
+ ":store_client",
+ ]
+}
+
+js_library("constants") {
+}
+
+js_library("dom_switch") {
+}
+
+js_library("fake_page_handler") {
+ deps = [
+ ":constants",
+ ":types",
+ ":util",
+ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
+js_library("main_view") {
+ deps = [
+ ":app_item",
+ ":browser_proxy",
+ ":constants",
+ ":store_client",
+ "//ui/webui/resources/js:load_time_data",
+ ]
+}
+
+js_library("permission_item") {
+ deps = [
+ ":fake_page_handler",
+ ":permission_toggle",
+ ":store_client",
+ ":util",
+ ]
+}
+
+js_library("permission_toggle") {
+ deps = [
+ ":util",
+ ]
+}
+
+js_library("pin_to_shelf_item") {
+ deps = [
+ ":browser_proxy",
+ ":toggle_row",
+ ":types",
+ ]
+}
+
+js_library("pwa_permission_view") {
+ deps = [
+ ":constants",
+ ":fake_page_handler",
+ ":permission_item",
+ ":pin_to_shelf_item",
+ ":store_client",
+ ]
+}
+
+js_library("reducers") {
+ deps = [
+ ":types",
+ ":util",
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
+js_library("router") {
+ deps = [
+ ":actions",
+ ":constants",
+ ":store_client",
+ ]
+}
+
+js_library("store") {
+ deps = [
+ ":reducers",
+ ":util",
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js/cr/ui:store",
+ ]
+}
+
+js_library("store_client") {
+ deps = [
+ ":store",
+ ":types",
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js/cr/ui:store",
+ "//ui/webui/resources/js/cr/ui:store_client",
+ ]
+}
+
+js_library("toggle_row") {
+ deps = [
+ ":types",
+ "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle",
+ "//ui/webui/resources/cr_elements/policy:cr_policy_indicator",
+ ]
+}
+
+js_library("types") {
+ deps = [
+ "//chrome/browser/ui/webui/app_management:mojo_bindings_js_library_for_compile",
+ ]
+}
+
+js_library("uninstall_button") {
+ deps = [
+ ":store_client",
+ ":util",
+ "//ui/webui/resources/cr_elements/cr_button:cr_button",
+ "//ui/webui/resources/cr_elements/policy:cr_tooltip_icon",
+ ]
+}
+
+js_library("util") {
+ deps = [
+ ":constants",
+ ":types",
+ "//ui/webui/resources/js:cr",
+ ]
+}
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 a1b5d3d633d..38ac772a9b0 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
@@ -20,7 +20,6 @@ js_library("smb_shares_page") {
js_library("os_files_page") {
deps = [
- "../..:page_visibility",
"../..:route",
]
}
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 85fc4d825ac..42ff0d047c9 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
@@ -7,28 +7,27 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":os_powerwash_dialog",
+ ":os_reset_browser_proxy",
":os_reset_page",
- ":reset_os_proxy",
]
}
js_library("os_powerwash_dialog") {
deps = [
- ":reset_os_proxy",
+ ":os_reset_browser_proxy",
"../..:lifetime_browser_proxy",
]
}
js_library("os_reset_page") {
deps = [
- "../..:page_visibility",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
}
-js_library("reset_os_proxy") {
+js_library("os_reset_browser_proxy") {
deps = [
"//ui/webui/resources/js:cr",
]
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 397f4d3e434..3c3c14e9d3d 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
@@ -12,7 +12,6 @@ js_type_check("closure_compile") {
js_library("os_settings_menu") {
deps = [
- "../..:page_visibility",
"../..:route",
"//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 e34d80d6362..11525a13645 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
@@ -17,6 +17,7 @@ js_library("os_settings_page") {
"../..:search_settings",
"../../android_apps_page:android_apps_browser_proxy",
"../../chrome_cleanup_page:chrome_cleanup_proxy",
+ "../../prefs:prefs_behavior",
"../../settings_page:main_page_behavior",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:web_ui_listener_behavior",
diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
index b098e77ce26..058863d4b69 100644
--- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn
@@ -16,10 +16,10 @@ js_library("os_settings_ui") {
"../..:page_visibility",
"../../prefs",
"../os_settings_main:os_settings_main",
+ "../os_toolbar",
"//ui/webui/resources/cr_elements:cr_container_shadow_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/cr_elements/cr_drawer:cr_drawer",
- "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar",
"//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field",
"//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior",
"//ui/webui/resources/js:find_shortcut_behavior",
diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn
new file mode 100644
index 00000000000..3ac49b91c8f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":os_toolbar",
+ ]
+}
+
+js_library("os_toolbar") {
+ deps = [
+ "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field",
+ ]
+ externs_list = [ "$externs_path/web_animations.js" ]
+}
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 7e68a1627b6..ca1cedfb81c 100644
--- a/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn
@@ -6,21 +6,13 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
- ":personalization_browser_proxy",
":personalization_page",
]
}
-js_library("personalization_browser_proxy") {
- deps = [
- "//ui/webui/resources/js:cr",
- ]
- externs_list = [ "$externs_path/chrome_send.js" ]
-}
-
js_library("personalization_page") {
deps = [
- ":personalization_browser_proxy",
+ "../../appearance_page:wallpaper_browser_proxy",
"../../settings_page:settings_animated_pages",
"//ui/webui/resources/js:cr",
]
diff --git a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html
index d58fdddf3d8..4a0026ee454 100644
--- a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html
+++ b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html
@@ -8,19 +8,18 @@
<dom-module id="settings-password-prompt-dialog">
<template>
<style include="settings-shared">
- #passwordInput {
- display: inline-block;
+ cr-dialog::part(dialog) {
+ width: 320px;
}
- .settings-box {
+ #passwordPrompt {
padding: 0;
}
</style>
-
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">$i18n{passwordPromptTitle}</div>
<div slot="body">
- <div class="settings-box first">
+ <div id="passwordPrompt" class="settings-box first line-only">
[[passwordPromptText]]
</div>
<cr-input id="passwordInput" type="password"
diff --git a/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js b/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js
index 51bbe0199f2..8db2d75dc99 100644
--- a/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js
+++ b/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js
@@ -37,6 +37,10 @@ const PrefControlBehavior = {
}
error += ' in ' + this.domHost.tagName;
console.error(error);
+ } else if (
+ this.pref.enforcement ==
+ chrome.settingsPrivate.Enforcement.PARENT_SUPERVISED) {
+ console.error('PARENT_SUPERVISED is not enforced by pref controls');
}
});
},
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/BUILD.gn b/chromium/chrome/browser/resources/settings/crostini_page/BUILD.gn
index db0a920aee3..2e4035eae4a 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/crostini_page/BUILD.gn
@@ -24,6 +24,7 @@ js_library("crostini_browser_proxy") {
js_library("crostini_export_import") {
deps = [
":crostini_browser_proxy",
+ "//ui/webui/resources/js:web_ui_listener_behavior",
]
}
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js b/chromium/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js
index 225da323ed6..f9b965ea621 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_browser_proxy.js
@@ -51,14 +51,26 @@ cr.define('settings', function() {
*/
removeCrostiniSharedPath(vmName, path) {}
- /* Request chrome send a crostini-installer-status-changed event with the
- current installer status */
+ /**
+ * Request chrome send a crostini-installer-status-changed event with the
+ * current installer status
+ */
requestCrostiniInstallerStatus() {}
- /* Export crostini container. */
+ /**
+ * Request chrome send a crostini-export-import-operation-status-changed
+ * event with the current operation status
+ */
+ requestCrostiniExportImportOperationStatus() {}
+
+ /**
+ * Export crostini container.
+ */
exportCrostiniContainer() {}
- /* Import crostini container. */
+ /**
+ * Import crostini container.
+ */
importCrostiniContainer() {}
}
@@ -100,6 +112,11 @@ cr.define('settings', function() {
}
/** @override */
+ requestCrostiniExportImportOperationStatus() {
+ chrome.send('requestCrostiniExportImportOperationStatus');
+ }
+
+ /** @override */
exportCrostiniContainer() {
chrome.send('exportCrostiniContainer');
}
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.html b/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.html
index 88989b88f9c..43c4d73d8da 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.html
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.html
@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="crostini_browser_proxy.html">
<link rel="import" href="crostini_import_confirmation_dialog.html">
<link rel="import" href="../i18n_setup.html">
@@ -15,18 +16,18 @@
<div id="exportCrostiniLabel" class="start secondary">
$i18n{crostiniExportLabel}
</div>
- <cr-button on-click="onExportClick_"
- aria-labelledby="exportCrostiniLabel">
- $i18n{crostiniExport}
+ <cr-button on-click="onExportClick_" disabled="[[!enableButtons_]]"
+ aria-labelledby="exportCrostiniLabel">
+ $i18n{crostiniExport}
</cr-button>
</div>
<div id="import" class="list-item">
<div id="importCrostiniLabel" class="start secondary">
$i18n{crostiniImportLabel}
</div>
- <cr-button on-click="onImportClick_"
- aria-labelledby="importCrostiniLabel">
- $i18n{crostiniImport}
+ <cr-button on-click="onImportClick_" disabled="[[!enableButtons_]]"
+ aria-labelledby="importCrostiniLabel">
+ $i18n{crostiniImport}
</cr-button>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.js b/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.js
index fa1be63a919..1cb7d34abc2 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.js
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_export_import.js
@@ -11,12 +11,33 @@
Polymer({
is: 'settings-crostini-export-import',
+ behaviors: [WebUIListenerBehavior],
+
properties: {
/** @private */
showImportConfirmationDialog_: {
type: Boolean,
value: false,
},
+
+ /**
+ * Whether the export import buttons should be enabled. Initially false
+ * until status has been confirmed.
+ * @private {boolean}
+ */
+ enableButtons_: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
+ attached: function() {
+ this.addWebUIListener(
+ 'crostini-export-import-operation-status-changed', inProgress => {
+ this.enableButtons_ = !inProgress;
+ });
+ settings.CrostiniBrowserProxyImpl.getInstance()
+ .requestCrostiniExportImportOperationStatus();
},
/** @private */
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.html b/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.html
index 1949eb2f98f..d241d5baf3a 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.html
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.html
@@ -43,7 +43,7 @@
<template is="dom-if" if="[[!prefs.crostini.enabled.value]]">
<div class="separator"></div>
<cr-button id="enable"
- disabled="[[!allowCrostini]]"
+ disabled$="[[disableCrostiniInstall_]]"
on-click="onEnableTap_"
aria-label="$i18n{crostiniPageTitle}"
aria-describedby="secondaryText">
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.js b/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.js
index 1f2b08a13e9..7a74d5b5fbd 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.js
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_page.js
@@ -12,7 +12,7 @@
Polymer({
is: 'settings-crostini-page',
- behaviors: [I18nBehavior, PrefsBehavior],
+ behaviors: [I18nBehavior, PrefsBehavior, WebUIListenerBehavior],
properties: {
/** Preferences state. */
@@ -49,6 +49,27 @@ Polymer({
return map;
},
},
+
+ /**
+ * Whether the install option should be enabled.
+ * @private {boolean}
+ */
+ disableCrostiniInstall_: {
+ type: Boolean,
+ },
+ },
+
+ attached: function() {
+ if (!loadTimeData.getBoolean('allowCrostini')) {
+ this.disableCrostiniInstall_ = true;
+ return;
+ }
+ this.addWebUIListener(
+ 'crostini-installer-status-changed', (installerShowing) => {
+ this.disableCrostiniInstall_ = installerShowing;
+ });
+ settings.CrostiniBrowserProxyImpl.getInstance()
+ .requestCrostiniInstallerStatus();
},
/**
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.html b/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.html
index 125be381c77..c77f6161ec1 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.html
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.html
@@ -17,14 +17,12 @@
label="$i18n{crostiniSharedPaths}"
on-click="onSharedPathsClick_">
</cr-link-row>
- <template is="dom-if" if="[[enableCrostiniUsbDeviceSupport_]]">
- <cr-link-row
- class="hr"
- label="$i18n{crostiniSharedUsbDevicesLabel}"
- id="crostini-shared-usb-devices"
- on-click="onSharedUsbDevicesClick_">
- </cr-link-row>
- </template>
+ <cr-link-row
+ class="hr"
+ label="$i18n{crostiniSharedUsbDevicesLabel}"
+ id="crostini-shared-usb-devices"
+ on-click="onSharedUsbDevicesClick_">
+ </cr-link-row>
<template is="dom-if" if="[[showCrostiniExportImport_]]">
<cr-link-row
class="hr"
diff --git a/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.js b/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.js
index 736b8a86e4b..66d8ca13fce 100644
--- a/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.js
+++ b/chromium/chrome/browser/resources/settings/crostini_page/crostini_subpage.js
@@ -20,17 +20,6 @@ Polymer({
},
/**
- * Whether CrostiniUsbSupport flag is enabled.
- * @private {boolean}
- */
- enableCrostiniUsbDeviceSupport_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('enableCrostiniUsbDeviceSupport');
- },
- },
-
- /**
* Whether export / import UI should be displayed.
* @private {boolean}
*/
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
index 735549d7721..1575327101d 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
+++ b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.html
@@ -65,7 +65,11 @@
</settings-toggle-button>
<cr-link-row class="hr" id="setDateTime"
on-click="onSetDateTimeTap_" hidden$="[[!canSetDateTime_]]"
- label="$i18n{setDateTime}"></cr-link-row>
+ label="$i18n{setDateTime}">
+ <template is="dom-if" if="[[displayManagedByParentIcon_]]">
+ <cr-policy-indicator indicator-type="parent"></cr-policy-indicator>
+ </template>
+ </cr-link-row>
</div>
<template is="dom-if" route-path="/dateTime/timeZone">
<settings-subpage data-route="DATETIME_TIMEZONE_SUBPAGE"
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
index 186c536e121..f5f8a8f3761 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
+++ b/chromium/chrome/browser/resources/settings/date_time_page/date_time_page.js
@@ -58,6 +58,17 @@ Polymer({
/** @private */
isChild_: {type: Boolean, value: loadTimeData.getBoolean('isChild')},
+
+ /**
+ * Whether the icon informing that this action is managed by a parent is
+ * displayed.
+ * @private
+ */
+ displayManagedByParentIcon_: {
+ type: Boolean,
+ value: loadTimeData.getBoolean('isChild') &&
+ loadTimeData.getBoolean('timeActionsProtectedForChild')
+ },
},
/** @override */
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.html b/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.html
index 2ae2ba3226e..2ee6c254ec8 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.html
+++ b/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.html
@@ -36,7 +36,7 @@
<settings-dropdown-menu id="timeZoneResolveMethodDropdown"
pref="{{prefs.generated.resolve_timezone_by_geolocation_method_short}}"
label="$i18n{selectTimeZoneResolveMethod}"
- hidden="[[!prefs.generated.resolve_timezone_by_geolocation_on_off.value]]"
+ disabled="[[!prefs.generated.resolve_timezone_by_geolocation_on_off.value]]"
menu-options="[[getTimeZoneResolveMethodsList_(
prefs.generated.resolve_timezone_by_geolocation_method_short)]]">
</settings-dropdown-menu>
diff --git a/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.js b/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.js
index f77b53e820c..3e29c0d9f05 100644
--- a/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.js
+++ b/chromium/chrome/browser/resources/settings/date_time_page/timezone_subpage.js
@@ -27,22 +27,26 @@ Polymer({
*/
getTimeZoneResolveMethodsList_: function() {
const result = [];
+ const pref =
+ this.getPref('generated.resolve_timezone_by_geolocation_method_short');
// Make sure current value is in the list, even if it is not
// user-selectable.
- if (this.getPref('generated.resolve_timezone_by_geolocation_method_short')
- .value == settings.TimeZoneAutoDetectMethod.DISABLED) {
- result.push({
- value: settings.TimeZoneAutoDetectMethod.DISABLED,
- name: loadTimeData.getString('setTimeZoneAutomaticallyDisabled')
- });
+ if (pref.value == settings.TimeZoneAutoDetectMethod.DISABLED) {
+ // If disabled by policy, show the 'Automatic timezone disabled' label.
+ // Otherwise, just show the default string, since the control will be
+ // disabled as well.
+ const label = pref.controlledBy ?
+ loadTimeData.getString('setTimeZoneAutomaticallyDisabled') :
+ loadTimeData.getString('setTimeZoneAutomaticallyIpOnlyDefault');
+ result.push(
+ {value: settings.TimeZoneAutoDetectMethod.DISABLED, name: label});
}
result.push({
value: settings.TimeZoneAutoDetectMethod.IP_ONLY,
name: loadTimeData.getString('setTimeZoneAutomaticallyIpOnlyDefault')
});
- if (this.getPref('generated.resolve_timezone_by_geolocation_method_short')
- .value ==
+ if (pref.value ==
settings.TimeZoneAutoDetectMethod.SEND_WIFI_ACCESS_POINTS) {
result.push({
value: settings.TimeZoneAutoDetectMethod.SEND_WIFI_ACCESS_POINTS,
diff --git a/chromium/chrome/browser/resources/settings/device_page/device_page.html b/chromium/chrome/browser/resources/settings/device_page/device_page.html
index 1f22b1fe3e7..8eacafb0ba7 100644
--- a/chromium/chrome/browser/resources/settings/device_page/device_page.html
+++ b/chromium/chrome/browser/resources/settings/device_page/device_page.html
@@ -85,7 +85,7 @@
<template is="dom-if" if="[[androidEnabled_]]">
<template is="dom-if" route-path="/storage/externalStoragePreferences">
<settings-subpage
- associated-control="[[$$('#externalStoragePreferencesRow')]]"
+ associated-control="[[$$('#storageRow')]]"
page-title="$i18n{storageExternal}">
<settings-storage-external prefs="{{prefs}}">
</settings-storage-external>
diff --git a/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js
index 2c8a7bf3606..13fa10e6b8a 100644
--- a/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js
@@ -78,6 +78,14 @@ settings.NoteAppLockScreenSupport = {
*/
settings.NoteAppInfo;
+/**
+ * @typedef {{
+ * label: string,
+ * uuid: string
+ * }}
+ */
+settings.ExternalStorage;
+
cr.define('settings', function() {
/** @interface */
class DevicePageBrowserProxy {
@@ -154,6 +162,16 @@ cr.define('settings', function() {
* actions from the lock screen.
*/
setPreferredNoteTakingAppEnabledOnLockScreen(enabled) {}
+
+ /** Requests an external storage list update. */
+ updateExternalStorages() {}
+
+ /**
+ * |callback| is run when the list of plugged-in external storages is
+ * available after |updateExternalStorages| has been called.
+ * @param {function(Array<!settings.ExternalStorage>):void} callback
+ */
+ setExternalStoragesUpdatedCallback(callback) {}
}
/**
@@ -234,6 +252,16 @@ cr.define('settings', function() {
setPreferredNoteTakingAppEnabledOnLockScreen(enabled) {
chrome.send('setPreferredNoteTakingAppEnabledOnLockScreen', [enabled]);
}
+
+ /** @override */
+ updateExternalStorages() {
+ chrome.send('updateExternalStorages');
+ }
+
+ /** @override */
+ setExternalStoragesUpdatedCallback(callback) {
+ cr.addWebUIListener('onExternalStoragesUpdated', callback);
+ }
}
cr.addSingletonGetter(DevicePageBrowserProxyImpl);
diff --git a/chromium/chrome/browser/resources/settings/device_page/display_overscan_dialog.html b/chromium/chrome/browser/resources/settings/device_page/display_overscan_dialog.html
index 514f8d719b6..7fcd324f6fe 100644
--- a/chromium/chrome/browser/resources/settings/device_page/display_overscan_dialog.html
+++ b/chromium/chrome/browser/resources/settings/device_page/display_overscan_dialog.html
@@ -5,7 +5,7 @@
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-display-overscan-dialog">
@@ -55,7 +55,7 @@
<iron-icon icon="cr:expand-less"></iron-icon>
</div>
<div class="layout horizontal">
- <iron-icon icon="settings:chevron-left"></iron-icon>
+ <iron-icon icon="os-settings:chevron-left"></iron-icon>
<iron-icon icon="cr:expand-more"></iron-icon>
<iron-icon icon="cr:chevron-right"></iron-icon>
</div>
diff --git a/chromium/chrome/browser/resources/settings/device_page/pointers.html b/chromium/chrome/browser/resources/settings/device_page/pointers.html
index 95301b12bf5..fff070da29c 100644
--- a/chromium/chrome/browser/resources/settings/device_page/pointers.html
+++ b/chromium/chrome/browser/resources/settings/device_page/pointers.html
@@ -22,8 +22,8 @@
.subsection > settings-toggle-button,
.subsection > .settings-box {
- padding-left: 0;
- padding-right: 0;
+ padding-inline-end: 0;
+ padding-inline-start: 0;
}
</style>
<div id="mouse" hidden$="[[!hasMouse]]">
@@ -43,6 +43,12 @@
pref="{{prefs.settings.mouse.reverse_scroll}}"
label="$i18n{mouseReverseScroll}">
</settings-toggle-button>
+ <template is="dom-if" if="[[allowDisableAcceleration_]]">
+ <settings-toggle-button id="mouseAcceleration"
+ pref="{{prefs.settings.mouse.acceleration}}"
+ label="$i18n{pointerAccelerationLabel}">
+ </settings-toggle-button>
+ </template>
<div class="settings-box">
<div class="start" id="mouseSpeedLabel">$i18n{mouseSpeed}</div>
<settings-slider pref="{{prefs.settings.mouse.sensitivity2}}"
@@ -66,6 +72,12 @@
pref="{{prefs.settings.touchpad.enable_tap_dragging}}"
label="$i18n{tapDraggingLabel}">
</settings-toggle-button>
+ <template is="dom-if" if="[[allowDisableAcceleration_]]">
+ <settings-toggle-button id="touchpadAcceleration"
+ pref="{{prefs.settings.touchpad.acceleration}}"
+ label="$i18n{pointerAccelerationLabel}">
+ </settings-toggle-button>
+ </template>
<div class="settings-box">
<div class="start" id="touchpadSpeedLabel">$i18n{touchpadSpeed}</div>
<settings-slider id="touchpadSensitivity"
diff --git a/chromium/chrome/browser/resources/settings/device_page/pointers.js b/chromium/chrome/browser/resources/settings/device_page/pointers.js
index 4414214536d..1db873949f2 100644
--- a/chromium/chrome/browser/resources/settings/device_page/pointers.js
+++ b/chromium/chrome/browser/resources/settings/device_page/pointers.js
@@ -30,6 +30,17 @@ Polymer({
value: [1, 2, 3, 4, 5],
readOnly: true,
},
+
+ /**
+ * TODO(zentaro): Remove this conditional once the feature is launched.
+ * @private
+ */
+ allowDisableAcceleration_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('allowDisableMouseAcceleration');
+ },
+ },
},
// Used to correctly identify when the mouse button has been released.
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.html b/chromium/chrome/browser/resources/settings/device_page/storage.html
index 701623f33f3..f0a518e2572 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage.html
+++ b/chromium/chrome/browser/resources/settings/device_page/storage.html
@@ -217,7 +217,7 @@
</template>
<cr-link-row id="browsingDataSize" class="hr" on-click="onBrowsingDataTap_"
label="$i18n{storageItemBrowsingData}"
- sub-label="$i18n{storageSizeComputing}"></cr-link-row>
+ sub-label="$i18n{storageSizeComputing}" external></cr-link-row>
<template is="dom-if" if="[[androidRunning_]]">
<cr-link-row id="androidSize" class="hr" on-click="onAndroidTap_"
label="$i18n{storageItemAndroid}"
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.js b/chromium/chrome/browser/resources/settings/device_page/storage.js
index 211c28c7726..2717462da66 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage.js
+++ b/chromium/chrome/browser/resources/settings/device_page/storage.js
@@ -162,9 +162,7 @@ Polymer({
* @private
*/
onBrowsingDataTap_: function() {
- settings.navigateTo(
- settings.routes.CLEAR_BROWSER_DATA,
- /* dynamicParams */ null, /* removeSearch */ true);
+ window.open('chrome://settings/clearBrowserData');
},
/**
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage_external.html b/chromium/chrome/browser/resources/settings/device_page/storage_external.html
index e215e54f0d5..922c2613d1f 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage_external.html
+++ b/chromium/chrome/browser/resources/settings/device_page/storage_external.html
@@ -1,21 +1,32 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="storage_external_entry.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-storage-external">
<template>
- <style include="settings-shared"></style>
+ <style include="settings-shared">
+ h2 {
+ padding-inline-start: var(--cr-section-padding);
+ }
+
+ </style>
<div class="settings-box first">
<span>
$i18n{storageAndroidAppsExternalDrivesNote}
</span>
</div>
- <settings-toggle-button class="hr"
- pref="{{prefs.arc.has_access_to_removable_media}}"
- label="$i18n{storageAndroidAppsExternalDrives}">
- </settings-toggle-button>
+ <h2>$i18n{storageExternalStorageListHeader}</h2>
+ <iron-list id="removableDevices" preserve-focus
+ items="[[externalStorages_]]">
+ <template>
+ <storage-external-entry uuid="[[item.uuid]]" label="[[item.label]]"
+ prefs="{{prefs}}">
+ </storage-external-entry>
+ </template>
+ </iron-list>
</template>
<script src="storage_external.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage_external.js b/chromium/chrome/browser/resources/settings/device_page/storage_external.js
index 61f54f6fdf3..b52ab99a3ae 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage_external.js
+++ b/chromium/chrome/browser/resources/settings/device_page/storage_external.js
@@ -10,4 +10,50 @@
Polymer({
is: 'settings-storage-external',
+
+ behaviors: [WebUIListenerBehavior],
+
+ properties: {
+ /**
+ * List of the plugged-in external storages.
+ * @private {Arrray<!settings.ExternalStorage>}
+ */
+ externalStorages_: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ /** @private {!chrome.settingsPrivate.PrefObject} */
+ externalStorageVisiblePref_: {
+ type: Object,
+ value: function() {
+ return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+ },
+ },
+ },
+
+ /** @private {?settings.DevicePageBrowserProxy} */
+ browserProxy_: null,
+
+ /** @override */
+ created: function() {
+ this.browserProxy_ = settings.DevicePageBrowserProxyImpl.getInstance();
+ },
+
+ /** @override */
+ attached: function() {
+ this.browserProxy_.setExternalStoragesUpdatedCallback(
+ this.handleExternalStoragesUpdated_.bind(this));
+ this.browserProxy_.updateExternalStorages();
+ },
+
+ /**
+ * @param {Array<!settings.ExternalStorage>} storages
+ * @private
+ */
+ handleExternalStoragesUpdated_: function(storages) {
+ this.externalStorages_ = storages;
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.html b/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.html
new file mode 100644
index 00000000000..c7f20266418
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.html
@@ -0,0 +1,25 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="../prefs/prefs.html">
+<link rel="import" href="../prefs/prefs_behavior.html">
+<link rel="import" href="../settings_shared_css.html">
+
+<dom-module id="storage-external-entry">
+ <template>
+ <style include="settings-shared">
+ settings-toggle-button {
+ margin-inline-end: var(--cr-section-padding);
+ margin-inline-start: var(--cr-section-indent-padding);
+ padding-inline-end: 0;
+ padding-inline-start: 0;
+ }
+ </style>
+ <settings-toggle-button class="hr"
+ pref="{{visiblePref_}}"
+ label="[[label]]"
+ on-settings-boolean-control-change="onVisibleChange_">
+ </settings-toggle-button>
+ </template>
+ <script src="storage_external_entry.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.js b/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.js
new file mode 100644
index 00000000000..8749afa8033
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/device_page/storage_external_entry.js
@@ -0,0 +1,72 @@
+// 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
+ * 'storage-external-entry' is the polymer element for showing a certain
+ * external storage device with a toggle switch. When the switch is ON,
+ * the storage's uuid will be saved to a preference.
+ */
+Polymer({
+ is: 'storage-external-entry',
+
+ behaviors: [WebUIListenerBehavior, PrefsBehavior],
+
+ properties: {
+ /**
+ * FileSystem UUID of an external storage.
+ */
+ uuid: String,
+
+ /**
+ * Label of an external storage.
+ */
+ label: String,
+
+ /** @private {chrome.settingsPrivate.PrefObject} */
+ visiblePref_: {
+ type: Object,
+ value: function() {
+ return /** @type {chrome.settingsPrivate.PrefObject} */ ({});
+ },
+ },
+ },
+
+ observers: [
+ 'updateVisible_(prefs.arc.visible_external_storages.*)',
+ ],
+
+ /**
+ * Handler for when the toggle button for this entry is clicked by a user.
+ * @param {!Event} event
+ * @private
+ */
+ onVisibleChange_: function(event) {
+ const visible = !!event.target.checked;
+ if (visible) {
+ this.appendPrefListItem('arc.visible_external_storages', this.uuid);
+ } else {
+ this.deletePrefListItem('arc.visible_external_storages', this.uuid);
+ }
+ chrome.metricsPrivate.recordBoolean(
+ 'Arc.ExternalStorage.SetVisible', visible);
+ },
+
+ /**
+ * Updates |visiblePref_| by reading the preference and check if it contains
+ * UUID of this storage.
+ * @private
+ */
+ updateVisible_: function() {
+ const uuids = /** @type {!Array<string>} */ (
+ this.getPref('arc.visible_external_storages').value);
+ const visible = uuids.some((id) => id === this.uuid);
+ const pref = {
+ key: '',
+ type: chrome.settingsPrivate.PrefType.BOOLEAN,
+ value: visible,
+ };
+ this.visiblePref_ = pref;
+ },
+}); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
index a901f4e32bd..559d65184d1 100644
--- a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
+++ b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js
@@ -16,7 +16,7 @@ const DspHotwordState = {
* Indicates user's activity control consent status.
*
* Note: This should be kept in sync with ash::mojom::ConsentStatus in
- * ash/public/interfaces/voice_interaction_controller.mojom
+ * ash/public/mojom/voice_interaction_controller.mojom
* @enum {number}
*/
const ConsentStatus = {
diff --git a/chromium/chrome/browser/resources/settings/icons.html b/chromium/chrome/browser/resources/settings/icons.html
index 816bb70c3a1..ad722128231 100644
--- a/chromium/chrome/browser/resources/settings/icons.html
+++ b/chromium/chrome/browser/resources/settings/icons.html
@@ -4,6 +4,7 @@
<!--
List icons here rather than importing large sets of (e.g. Polymer) icons.
+NOTE: Chrome OS icons go in ./chromeos/os_icons.html.
-->
<iron-iconset-svg name="settings20" size="20">
<svg>
@@ -12,10 +13,17 @@ List icons here rather than importing large sets of (e.g. Polymer) icons.
<g id="googleg"><path d="M16.58 8H9v2.75h4.47c-.24 1.2-1.42 3.27-4.47 3.27-2.72 0-4.93-2.25-4.93-5.02S6.28 3.98 9 3.98c1.54 0 2.57.66 3.17 1.22l2.19-2.12C12.97 1.79 11.16 1 9 1 4.58 1 1 4.58 1 9s3.58 8 8 8c4.62 0 7.68-3.25 7.68-7.82 0-.46-.04-.83-.1-1.18z"></path></g>
<g id="location-on"><path d="M10,2 C6.95928571,2 4.5,4.504 4.5,7.6 C4.5,11.8 10,18 10,18 C10,18 15.5,11.8 15.5,7.6 C15.5,4.504 13.0407143,2 10,2 Z M10,9.5 C8.896,9.5 8,8.604 8,7.5 C8,6.396 8.896,5.5 10,5.5 C11.104,5.5 12,6.396 12,7.5 C12,8.604 11.104,9.5 10,9.5 Z"></path></g>
<g id="vpn-key"><path d="M10.4727273,8 C9.87272727,6.2525 8.26181818,5 6.36363636,5 C3.95272727,5 2,7.01375 2,9.5 C2,11.98625 3.95272727,14 6.36363636,14 C8.26181818,14 9.87272727,12.7475 10.4727273,11 L13.6363636,11 L13.6363636,14 L16.5454545,14 L16.5454545,11 L18,11 L18,8 L10.4727273,8 Z M6.36363636,11 C5.56,11 4.90909091,10.32875 4.90909091,9.5 C4.90909091,8.67125 5.56,8 6.36363636,8 C7.16727273,8 7.81818182,8.67125 7.81818182,9.5 C7.81818182,10.32875 7.16727273,11 6.36363636,11 Z"></path></g>
+ <g id="cloud-off"><path d="M16.4732571,13.3443682 C16.8002856,12.9882746 17,12.5134184 17,11.9922 C17,10.8882 16.104,9.9922 15,9.9922 L13.494,9.9922 L13.494,9.0002 C13.494,7.0672 11.927,5.5002 9.994,5.5002 C9.5847901,5.5002 9.1930204,5.57089988 8.82954884,5.70065995 L7.33083687,4.20194798 C8.11843435,3.75577808 9.02717677,3.5002 10,3.5002 C12.71,3.5002 14.957,5.4612 15.411,8.0412 C17.424,8.2502 19,9.9312 19,12.0002 C19,13.0718701 18.5784721,14.0451601 17.8921876,14.7632987 L16.4732571,13.3443682 Z M17.8711111,17 L16.8711111,18 L14.8713111,16.0002 L6,16.0002 C3.239,16.0002 1,13.7622 1,11.0002 C1,8.58475294 2.71868905,6.59044755 4.99627833,6.12516722 L2,3.12888889 L3,2.12888889 L17.8711111,17 Z M6.86331111,7.9922 L6,7.9922 C4.343,7.9922 3,9.3352 3,10.9922 C3,12.6492 4.343,13.9922 6,13.9922 L12.8633111,13.9922 L6.86331111,7.9922 Z"></path></g>
+ <!-- The polygon ("+" shape) within this icon will always be filled with
+ the color #4285F4. Any color fills specified programmatically will
+ only be applied to the outer layer. -->
+ <g id="printer-add"><path d="M17.8734304,8.29826826 C17.2839707,8.10470383 16.6542128,8 16,8 C13.3875623,8 11.1650842,9.66961525 10.3414114,12 L7,12 L7,15 L10.0829584,15 C10.2034032,15.7179235 10.4513404,16.3926158 10.8026932,17 L5,17 L5,14 L2,14 L2,9 C2,7.8954305 2.8954305,7 4,7 L5,7 L5,3 L15,3 L15,7 L16,7 C16.8576527,7 17.5892179,7.53984453 17.8734304,8.29826826 Z M7,5 L7,7 L13,7 L13,5 L7,5 Z"></path><polygon fill="#4285F4" points="17 13 19 13 19 15 17 15 17 17 15 17 15 15 13 15 13 13 15 13 15 11 17 11"></polygon></g>
</defs>
</svg>
</iron-iconset-svg>
+<!-- NOTE: In the common case that the final icon will be 20x20, export the SVG
+ at 20px and place it in the section above. -->
<iron-iconset-svg name="settings" size="24">
<svg>
<defs>
@@ -38,31 +46,6 @@ List icons here rather than importing large sets of (e.g. Polymer) icons.
<path fill="none" d="M1 1h22v22H1z"></path>
</g>
-<if expr="chromeos">
- <!-- Icons from http://icons/ -->
- <g id="play-prism"><path d="M20.18 10.88l-3.06-1.74L14.26 12l2.86 2.86 3.06-1.74c.55-.31.82-.71.82-1.12 0-.41-.27-.81-.82-1.12zM4.71 2.45l8.42 8.42 2.55-2.55-10.7-6.06c-.07-.04-.14-.07-.21-.1-.17-.07-.3.05-.15.21.03.02.06.05.09.08zm0 19.1l-.08.08c-.15.15-.02.28.15.21.07-.03.14-.06.21-.1l10.69-6.06-2.55-2.55s-7.2 7.21-8.42 8.42zM12 12L3.38 3.38c-.19-.19-.38-.07-.38.19v16.86c0 .26.19.38.38.19L12 12z"></path></g>
-
- <!-- Apps icon for Settings drawer -->
- <g id="apps">
- <rect width="24" height="24"></rect>
- <path d="M6 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6 12c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-6 0c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0-6c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6 0c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4-8c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zm-4 2c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6 6c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 6c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"></path>
- </g>
-
- <!-- Crostini Mascot icon for Settings drawer -->
- <g id="crostini-mascot" fill-rule="evenodd">
- <rect width="24" height="24" fill="none"></rect>
- <path d="M6.70994751,22.1802367 C3.77039152,20.9576222 1.88689678,18.4876617 1.82270453,14.1866283 C1.52620735,14.3410271 1.18877909,14.3669908 0.800057996,14.221322 C-0.312414045,13.804436 -0.0624529958,12.4120387 0.345560769,11.1705211 C0.68346303,10.142341 1.83735671,9.39181671 2.40240955,9.23479478 C3.71763772,4.05541221 6.80346772,0 12,0 C17.2584272,0 20.3654882,3.88805047 21.6436562,9.24850027 C22.2231374,9.43172978 23.3254781,10.1695473 23.6544392,11.1705211 C24.062453,12.4120387 24.312414,13.804436 23.199942,14.221322 C22.8112853,14.3669667 22.4739044,14.3410357 22.1774428,14.186705 C22.1189307,18.5169382 20.2342349,20.9750038 17.2936622,22.1879533 C17.3379726,22.2841737 17.3614392,22.3916932 17.3614392,22.5115654 C17.3614392,23.3336051 17.750632,24 14.8965517,24 C12.813813,24 12.4581871,23.5470722 12.4180882,23.0543665 C12.2796354,22.9647547 12.14026,22.8305157 12,22.8305157 C11.8594243,22.8305157 11.7197425,22.9755283 11.5809922,23.0650454 C11.536581,23.553597 11.171131,24 9.10344828,24 C6.24936798,24 6.63856075,23.3336051 6.63856075,22.5115654 C6.63856075,22.3884786 6.66330281,22.278416 6.70994751,22.1802367 Z M12,20.3378361 C17.4851654,20.3378361 19.4630542,17.934489 19.4630542,12.6147346 C19.4630542,8.20063746 17.6641739,4.14700996 14.6790451,3.47027327 C13.7222433,3.25336374 13.052482,5.61336212 12,5.61336212 C10.947518,5.61336212 10.1820765,3.25336374 9.32095491,3.47027327 C6.32316904,4.22539115 4.53694581,8.43392639 4.53694581,12.6147346 C4.53694581,17.6346061 6.51483457,20.3378361 12,20.3378361 Z M8.27586207,9.99377535 C7.59026721,9.99377535 7.03448276,9.42257974 7.03448276,8.71797424 C7.03448276,8.01336875 7.59026721,7.44217314 8.27586207,7.44217314 C8.96145693,7.44217314 9.51724138,8.01336875 9.51724138,8.71797424 C9.51724138,9.42257974 8.96145693,9.99377535 8.27586207,9.99377535 Z M15.7241379,9.99377535 C15.0385431,9.99377535 14.4827586,9.42257974 14.4827586,8.71797424 C14.4827586,8.01336875 15.0385431,7.44217314 15.7241379,7.44217314 C16.4097328,7.44217314 16.9655172,8.01336875 16.9655172,8.71797424 C16.9655172,9.42257974 16.4097328,9.99377535 15.7241379,9.99377535 Z M12.224615,10.6827627 L13.9283449,11.4510541 C14.2234366,11.5841248 14.3564393,11.9349546 14.2254148,12.2346546 C14.1996198,12.293657 14.1645229,12.3479919 14.1215061,12.39552 L12.4275305,14.2671455 C12.2090286,14.5085621 11.8392003,14.5243719 11.6014958,14.3024578 C11.5890079,14.2907994 11.5770255,14.2785946 11.5655826,14.265878 L9.87720766,12.3895636 C9.65939502,12.1475054 9.67603268,11.771949 9.91436891,11.5507349 C9.9604013,11.5080095 10.012868,11.4730393 10.0697797,11.4471502 L11.7484004,10.6835476 C11.8998356,10.6146599 12.0729604,10.6143745 12.224615,10.6827627 Z"></path>
- </g>
-
- <!-- Plugin VM icon for Settings drawer -->
- <g id="plugin-vm"><path transform="scale(1.2)" d="M7 12v4H4V4a1 1 0 0 1 1-1h8a3 3 0 0 1 3 3v3a3 3 0 0 1-3 3H7zm0-6v3h5a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1H7z"></path></g>
-
- <!-- Icons for MultiDevice Settings UI -->
- <g id="multidevice-better-together-suite"><path d="M17,1.01 L7,1 C5.9,1 5,1.9 5,3 L5,21 C5,22.1 5.9,23 7,23 L17,23 C18.1,23 19,22.1 19,21 L19,3 C19,1.9 18.1,1.01 17,1.01 Z M17,21 L7,21 L7,20 L17,20 L17,21 Z M17,18 L7,18 L7,6 L17,6 L17,18 Z M7,4 L7,3 L17,3 L17,4 L7,4 Z"></path></g>
- <g id="multidevice-smart-lock"><path d="M18,9 L17,9 L17,7 C17,4.24 14.76,2 12,2 C9.24,2 7,4.24 7,7 L7,9 L6,9 C4.9,9 4,9.9 4,11 L4,21 C4,22.1 4.9,23 6,23 L18,23 C19.1,23 20,22.1 20,21 L20,11 C20,9.9 19.1,9 18,9 Z M9,7 C9,5.34 10.34,4 12,4 C13.66,4 15,5.34 15,7 L15,9 L9,9 L9,7 Z M18,21 L6,21 L6,11 L18,11 L18,21 Z M12,18 C13.1,18 14,17.1 14,16 C14,14.9 13.1,14 12,14 C10.9,14 10,14.9 10,16 C10,17.1 10.9,18 12,18 Z"></path></g>
- <g id="multidevice-messages"><path d="M19.9593506,2 C21.0593506,2 22,2.89658203 22,3.99658203 L22,16.0036621 C22,17.1036621 21.0593506,18.0036621 19.9593506,18.0036621 L6.00878906,18.0036621 L2.00878906,22.4 L2.01878906,3.99658203 C2.01878906,2.89658203 2.90878906,2 4.00878906,2 L19.9593506,2 Z M8,8.56896973 L4.5,12 L8,15.6103516 L8,13 L14,13 L14,11 L8,11 L8,8.56896973 Z M20.5688477,7 L17,3.57207031 L17,6 L11,6 L11,8 L17,8 L17,10.5720703 L20.5688477,7 Z"></path></g>
-</if>
-
<!-- Protected Content SVG -->
<g id="protected-content">
<path d="M10,15 L6,11.1783439 L7.41,9.83121019 L10,12.2961783 L16.59,6 L18,7.3566879 L10,15 Z M21,3 L3,3 C1.89,3 1,3.89 1,5 L1,17 C1,18.1 1.89,19 3,19 L8,19 L8,21 L16,21 L16,19 L21,19 C22.1,19 22.99,18.1 22.99,17 L23,5 C23,3.89 22.1,3 21,3 Z M21,17 L3,17 L3,5 L21,5 L21,17 Z"></path>
@@ -72,50 +55,21 @@ List icons here rather than importing large sets of (e.g. Polymer) icons.
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.
-->
-<if expr="chromeos">
- <g id="access-time"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"></path></g>
-</if>
<g id="accessibility"><path d="M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z"></path></g>
<g id="apps"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"></path></g>
<g id="assignment"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"></path></g>
-<if expr="chromeos">
- <g id="bluetooth-connected"><path d="M7 12l-2-2-2 2 2 2 2-2zm10.71-4.29L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88zM19 10l-2 2 2 2 2-2-2-2z"></path></g>
- <g id="bluetooth-disabled"><path d="M13 5.83l1.88 1.88-1.6 1.6 1.41 1.41 3.02-3.02L12 2h-1v5.03l2 2v-3.2zM5.41 4L4 5.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l4.29-4.29 2.3 2.29L20 18.59 5.41 4zM13 18.17v-3.76l1.88 1.88L13 18.17z"></path></g>
- <g id="brightness-1"><circle cx="12" cy="12" r="10"></circle></g>
-</if>
<if expr="not chromeos">
<g id="build"><path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"></path></g>
</if>
<g id="check-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path></g>
-<if expr="chromeos">
- <g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"</path></g>
-</if>
<g id="clipboard"><path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path></g>
<g id="cloud"><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.96z"></path></g>
<g id="code"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></g>
<g id="content-copy"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path></g>
-<if expr="chromeos">
- <g id="devices-other"><path d="M3 6h18V4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V6zm10 6H9v1.78c-.61.55-1 1.33-1 2.22s.39 1.67 1 2.22V20h4v-1.78c.61-.55 1-1.34 1-2.22s-.39-1.67-1-2.22V12zm-2 5.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM22 8h-6c-.5 0-1 .5-1 1v10c0 .5.5 1 1 1h6c.5 0 1-.5 1-1V9c0-.5-.5-1-1-1zm-1 10h-4v-8h4v8z"></path></g>
-</if>
<g id="exit-to-app"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path></g>
-<if expr="chromeos">
- <g id="fingerprint"><path d="M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41-.24.13-.54.04-.68-.2-.13-.24-.04-.55.2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67-.09.18-.26.28-.44.28zM3.5 9.72c-.1 0-.2-.03-.29-.09-.23-.16-.28-.47-.12-.7.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25.16.22.11.54-.12.7-.23.16-.54.11-.7-.12-.9-1.26-2.04-2.25-3.39-2.94-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07c-.13 0-.26-.05-.35-.15-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1-1.4-1.39-2.17-3.24-2.17-5.22 0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29-.49-1.31-.73-2.61-.73-3.96 0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z"></path></g>
- <g id="gamepad"><path d="M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z"></path></g>
- <g id="headset"><path d="M12 1c-4.97 0-9 4.03-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-4v8h3c1.66 0 3-1.34 3-3v-7c0-4.97-4.03-9-9-9z"></path></g>
- <g id="keyboard"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"></path></g>
-</if>
<g id="language"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"></path></g>
-<if expr="chromeos">
- <g id="laptop-chromebook"><path d="M22 18V3H2v15H0v2h24v-2h-2zm-8 0h-4v-1h4v1zm6-3H4V5h16v10z"></path></g>
-</if>
<g id="midi"><path d="M21,19.1H3V5h18V19.1z M21,3H3C1.9,3,1,3.9,1,5v14c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"></path><path fill="none" d="M21,19.1H3V5h18V19.1z M21,3H3C1.9,3,1,3.9,1,5v14c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"></path><path d="M14,5h3v8h-3V5z"></path><path d="M15,12h1v8h-1V12z"></path><path fill="none" d="M0,0h24v24H0V0z"></path><rect x="7" y="5" width="3" height="8"></rect><rect x="8" y="12" width="1" height="8"></rect></g>
-<if expr="chromeos">
- <g id="mouse"><path d="M13 1.07V9h7c0-4.08-3.05-7.44-7-7.93zM4 15c0 4.42 3.58 8 8 8s8-3.58 8-8v-4H4v4zm7-13.93C7.05 1.56 4 4.92 4 9h7V1.07z"></path></g>
-</if>
<g id="music-note"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"></path></g>
-<if expr="chromeos">
- <g id="network-wifi"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"></path><path d="M3.53 10.95l8.46 10.54.01.01.01-.01 8.46-10.54C20.04 10.62 16.81 8 12 8c-4.81 0-8.04 2.62-8.47 2.95z"></path></g>
-</if>
<g id="notifications"><path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"></path></g>
<g id="pdf"><path d="M7 11.5h1v-1H7v1zM19 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-2zm-9.5 8.5c0 .83-.67 1.5-1.5 1.5H7v2H5.5V9H8c.83 0 1.5.67 1.5 1.5v1zm10-1H17v1h1.5V13H17v2h-1.5V9h4v1.5zm-5 3c0 .83-.67 1.5-1.5 1.5h-2.5V9H13c.83 0 1.5.67 1.5 1.5v3zm-2.5 0h1v-3h-1v3z"></path><path fill="none" d="M0 0h24v24H0z"></path></g>
<g id="palette"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></g>
@@ -125,29 +79,15 @@ List icons here rather than importing large sets of (e.g. Polymer) icons.
<g id="protocol-handler"><path d="M21.72 11.33l-6.644-7.035a.97.97 0 0 0-1.38-.01l-1.67 1.72-1.617-1.712a.97.97 0 0 0-1.38-.01l-6.737 6.935c-.187.191-.29.447-.292.719-.002.272.099.529.28.722l6.644 7.034a.949.949 0 0 0 1.38.011l1.671-1.718 1.615 1.71a.949.949 0 0 0 1.381.01l6.74-6.935a1.054 1.054 0 0 0 .01-1.44zM6.947 12.464l3.657 3.785-.974.98-5.273-5.456 5.349-5.378.929.962-3.677 3.7a.998.998 0 0 0-.292.702 1 1 0 0 0 .28.705zm7.35 4.768l-.931-.963 3.68-3.7a1.012 1.012 0 0 0 .007-1.407l-3.656-3.784.974-.98 5.273 5.456-5.348 5.378z"></path></g>
<g id="restore"><path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"></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="save-original"><path d="M16.058 24.876H8.002c-1.107 0-2.002-.94-2.002-2.088l.01-16.7C6.01 4.939 6.905 4 8.012 4h8.046l6.035 6.263v4.175h-2.011v-3.131h-5.03v-5.22h-7.04v16.701h4.023v2.088h4.023zm7.581-6.157l1.474 1.481-4.18 4.2-4.182-4.2 1.474-1.48 1.662 1.659V16h2.09v4.378l1.662-1.659zM26.308 28H15.557v-2.4h10.75V28z" id="a"></path></g>
<g id="sensors"><path d="M10 8.5c-0.8 0-1.5 0.7-1.5 1.5s0.7 1.5 1.5 1.5s1.5-0.7 1.5-1.5S10.8 8.5 10 8.5z M7.6 5.8 C6.2 6.7 5.2 8.2 5.2 10c0 1.8 1 3.4 2.4 4.2l0.8-1.4c-1-0.6-1.6-1.6-1.6-2.8c0-1.2 0.6-2.2 1.6-2.8L7.6 5.8z M14.8 10 c0-1.8-1-3.4-2.4-4.2l-0.8 1.4c0.9 0.6 1.6 1.6 1.6 2.8c0 1.2-0.6 2.2-1.6 2.8l0.8 1.4C13.8 13.4 14.8 11.8 14.8 10z M6 3 c-2.4 1.4-4 4-4 7c0 3 1.6 5.6 4 7l0.8-1.4c-1.9-1.1-3.2-3.2-3.2-5.6c0-2.4 1.3-4.5 3.2-5.6L6 3z M13.2 4.4 c1.9 1.1 3.2 3.2 3.2 5.6c0 2.4-1.3 4.5-3.2 5.6L14 17c2.4-1.4 4-4 4-7c0-3-1.6-5.6-4-7L13.2 4.4z"></path></g>
<g id="serial-port"><path d="M22 9V7h-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2v-2h-2V9h2zm-4 10H4V5h14v14zM6 13h5v4H6zm6-6h4v3h-4zM6 7h5v5H6zm6 4h4v6h-4z"></path></g>
-<if expr="chromeos">
- <g id="alert-device-out-of-range" fill="none" fill-rule="evenodd"><path d="M-1-1h20v20H-1z"></path><path fill="#C53929" fill-rule="nonzero" d="M8.167 11.5h1.666v1.667H8.167V11.5zm0-6.667h1.666v5H8.167v-5zM8.992.667C4.392.667.667 4.4.667 9s3.725 8.333 8.325 8.333c4.608 0 8.341-3.733 8.341-8.333S13.6.667 8.992.667zm.008 15A6.665 6.665 0 0 1 2.333 9 6.665 6.665 0 0 1 9 2.333 6.665 6.665 0 0 1 15.667 9 6.665 6.665 0 0 1 9 15.667z"></path></g>
- <g id="signal-cellular-0-bar"><path fill-opacity=".3" d="M2 22h20V2z"></path></g>
- <g id="signal-cellular-1-bar"><path fill-opacity=".3" d="M2 22h20V2z"></path><path d="M12 12L2 22h10z"></path></g>
- <g id="signal-cellular-2-bar"><path fill-opacity=".3" d="M2 22h20V2z"></path><path d="M14 10L2 22h12z"></path></g>
- <g id="signal-cellular-3-bar"><path fill-opacity=".3" d="M2 22h20V2z"></path><path d="M17 7L2 22h15z"></path></g>
- <g id="signal-cellular-4-bar"><path d="M2 22h20V2z"></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>
-</if>
<g id="supervisor-account"><path d="M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z"></path></g>
<g id="sync-disabled"><path d="M10 6.35V4.26c-.8.21-1.55.54-2.23.96l1.46 1.46c.25-.12.5-.24.77-.33zm-7.14-.94l2.36 2.36C4.45 8.99 4 10.44 4 12c0 2.21.91 4.2 2.36 5.64L4 20h6v-6l-2.24 2.24C6.68 15.15 6 13.66 6 12c0-1 .25-1.94.68-2.77l8.08 8.08c-.25.13-.5.25-.77.34v2.09c.8-.21 1.55-.54 2.23-.96l2.36 2.36 1.27-1.27L4.14 4.14 2.86 5.41zM20 4h-6v6l2.24-2.24C17.32 8.85 18 10.34 18 12c0 1-.25 1.94-.68 2.77l1.46 1.46C19.55 15.01 20 13.56 20 12c0-2.21-.91-4.2-2.36-5.64L20 4z"></path></g>
<g id="sync-problem"><path d="M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z"></path></g>
-<if expr="chromeos">
- <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>
-</if>
<g id="usb"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93 0-1.21-.99-2.2-2.2-2.2-1.21 0-2.2.99-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37-1.2 1.1-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2-.98 2.2-2.2 0-.85-.49-1.58-1.2-1.95V15h3c1.11 0 2-.89 2-2v-2h1V7h-4z"></path></g>
<g id="volume-up"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"></path></g>
<g id="bluetooth-scanning"><path d="M14.24 12.01l2.32 2.32c.28-.72.44-1.51.44-2.33 0-.82-.16-1.59-.43-2.31l-2.33 2.32zm5.29-5.3l-1.26 1.26c.63 1.21.98 2.57.98 4.02s-.36 2.82-.98 4.02l1.2 1.2a9.936 9.936 0 0 0 1.54-5.31c-.01-1.89-.55-3.67-1.48-5.19zm-3.82 1L10 2H9v7.59L4.41 5 3 6.41 8.59 12 3 17.59 4.41 19 9 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM11 5.83l1.88 1.88L11 9.59V5.83zm1.88 10.46L11 18.17v-3.76l1.88 1.88z"></path></g>
-<if expr="chromeos">
- <g id="end-of-life"><path d="M4.574 2.916H4.55l.01.01.014-.01zM2.5 4.968v.023a.18.18 0 0 1 .01-.013l-.01-.01zm14.585 10.49v-.024l-.01.013.01.01zm.223 1.817l-.933-.95-4.106-4.11L8.026 7.99 3.675 3.635l-.942-.941-.712-.713L1 3.002l1.733 1.733A9.056 9.056 0 0 0 1.05 9.98c0 1.95.628 3.748 1.683 5.22.574.8 1.274 1.501 2.074 2.075a8.918 8.918 0 0 0 5.218 1.684 8.918 8.918 0 0 0 5.218-1.684L16.991 19l1.02-1.021-.703-.704zM15.243 2.684A8.922 8.922 0 0 0 10.025 1a8.922 8.922 0 0 0-5.218 1.684c-.005.003 4.135 4.16 4.135 4.16l1.083-1.814L15.042 11h-1.846l4.11 4.214a8.939 8.939 0 0 0 .011-10.456 9.021 9.021 0 0 0-2.074-2.074zM12 15H7.012v-3.989L4.5 11l2.227-1.876L12 14.6v.4z" fill="#DB4437" fill-rule="evenodd"></path></g>
-</if>
<if expr="not chromeos">
<g id="web"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z"></path></g>
</if>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
index 936eea443b4..7b8a8fa0718 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
@@ -27,6 +27,7 @@ js_library("internet_page") {
"../settings_page:settings_animated_pages",
"//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile",
"//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
+ "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
@@ -35,7 +36,6 @@ js_library("internet_page") {
]
externs_list = [
"$externs_path/chrome_send.js",
- "$externs_path/management.js",
"$externs_path/networking_private.js",
]
extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
@@ -68,7 +68,7 @@ js_library("internet_detail_page") {
"..:route",
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+ "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
]
@@ -84,7 +84,7 @@ js_library("internet_known_networks_page") {
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+ "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo",
"//ui/webui/resources/js:assert",
]
externs_list = [ "$externs_path/networking_private.js" ]
@@ -96,7 +96,7 @@ js_library("internet_subpage") {
":internet_page_browser_proxy",
"..:route",
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+ "//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/chromeos:onc_mojo",
@@ -111,9 +111,10 @@ js_library("network_proxy_section") {
"../controls:settings_checkbox",
"../prefs:prefs_behavior",
"//ui/webui/resources/cr_components/chromeos/network:network_proxy",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+ "//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/chromeos:onc_mojo",
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
}
@@ -122,7 +123,6 @@ js_library("network_summary") {
deps = [
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js/chromeos:onc_mojo",
]
@@ -132,7 +132,7 @@ js_library("network_summary") {
js_library("network_summary_item") {
deps = [
"//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
- "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior",
+ "//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/chromeos:onc_mojo",
@@ -142,9 +142,9 @@ js_library("network_summary_item") {
js_library("tether_connection_dialog") {
deps = [
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:i18n_behavior",
+ "//ui/webui/resources/js/chromeos:onc_mojo",
]
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html
index a49a1d32fe9..c78ca56e50b 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -4,7 +4,7 @@
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_choose_mobile.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_ip_config.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_nameservers.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_property_list.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_property_list_mojo.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_siminfo.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_listener_behavior.html">
@@ -14,8 +14,9 @@
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator_mojo.html">
+<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
@@ -23,6 +24,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
<link rel="import" href="../controls/controlled_button.html">
<link rel="import" href="../controls/settings_toggle_button.html">
+<link rel="import" href="../i18n_setup.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../route.html">
<link rel="import" href="internet_page_browser_proxy.html">
@@ -49,7 +51,7 @@
margin-inline-start: var(--settings-control-label-spacing);
}
- cr-policy-network-indicator,
+ cr-policy-network-indicator-mojo,
cr-policy-indicator,
cr-policy-pref-indicator {
margin-inline-start: var(--settings-controlled-by-spacing);
@@ -76,72 +78,74 @@
<div class="start layout horizontal center">
<cr-network-icon
show-technology-badge="[[showTechnologyBadge_]]"
- network-state="[[getNetworkState_(networkProperties_)]]">
+ network-state="[[getNetworkState_(managedProperties_)]]">
</cr-network-icon>
<div id="networkState" class="title settings-box-text"
- connected$="[[isConnectedState_(networkProperties_)]]"
- error$="[[outOfRange_]]">
- [[getStateText_(networkProperties_, outOfRange_)]]
+ connected$="[[isConnectedState_(managedProperties_)]]"
+ error$="[[isConnectionErrorState_(
+ managedProperties_, outOfRange_)]]">
+ [[getStateText_(managedProperties_, propertiesReceived_,
+ outOfRange_)]]
</div>
<template is="dom-if"
- if="[[isPolicySource(networkProperties_.Source))]]">
+ if="[[isPolicySource(managedProperties_.source))]]">
<cr-policy-indicator
indicator-type="[[getIndicatorTypeForSource(
- networkProperties_.Source)]]">
+ managedProperties_.source)]]">
</cr-policy-indicator>
</template>
</div>
<cr-button on-click="onForgetTap_"
- hidden$="[[!showForget_(networkProperties_)]]"
- disabled="[[disableForget_(networkProperties_,
+ hidden$="[[!showForget_(managedProperties_)]]"
+ disabled="[[disableForget_(managedProperties_,
prefs.vpn_config_allowed)]]">
$i18n{networkButtonForget}
</cr-button>
<cr-button on-click="onViewAccountTap_"
- hidden$="[[!showViewAccount_(networkProperties_)]]">
+ hidden$="[[!showViewAccount_(managedProperties_)]]">
$i18n{networkButtonViewAccount}
</cr-button>
<cr-button on-click="onActivateTap_"
- hidden$="[[!showActivate_(networkProperties_)]]">
+ hidden$="[[!showActivate_(managedProperties_)]]">
$i18n{networkButtonActivate}
</cr-button>
<cr-button on-click="onConfigureTap_"
- hidden$="[[!showConfigure_(networkProperties_, globalPolicy,
+ hidden$="[[!showConfigure_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]"
- disabled="[[disableConfigure_(networkProperties_,
+ disabled="[[disableConfigure_(managedProperties_,
prefs.vpn_config_allowed)]]">
$i18n{networkButtonConfigure}
</cr-button>
<!-- Use policy properties from vpn_config_allowed to indicate when that
pref disables buttons in this row. -->
<controlled-button id="connect" action-button on-click="onConnectTap_"
- hidden$="[[!showConnect_(networkProperties_, globalPolicy,
+ hidden$="[[!showConnect_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]"
- disabled="[[!enableConnect_(networkProperties_, defaultNetwork,
- networkPropertiesReceived_, outOfRange_, globalPolicy,
+ disabled="[[!enableConnect_(managedProperties_, defaultNetwork,
+ propertiesReceived_, outOfRange_, globalPolicy,
managedNetworkAvailable)]]"
label="$i18n{networkButtonConnect}"
- pref="[[getFakeVpnConfigPrefForEnforcement_(networkProperties_,
+ pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_,
prefs.vpn_config_allowed)]]">
</controlled-button>
<controlled-button id="disconnect" action-button
on-click="onDisconnectTap_"
- hidden$="[[!showDisconnect_(networkProperties_)]]"
+ hidden$="[[!showDisconnect_(managedProperties_)]]"
label="$i18n{networkButtonDisconnect}"
- pref="[[getFakeVpnConfigPrefForEnforcement_(networkProperties_,
+ pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_,
prefs.vpn_config_allowed)]]">
</controlled-button>
</div>
<!-- Disabled by policy / Shared messages. -->
<div class="settings-box continuation"
- hidden$="[[!isBlockedByPolicy_(networkProperties_, globalPolicy,
+ hidden$="[[!isBlockedByPolicy_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]">
<iron-icon class="policy" icon="cr20:domain"></iron-icon>
<div class="settings-box-text">$i18n{networkConnectNotAllowed}</div>
</div>
<div class="settings-box continuation settings-box-text"
- hidden$="[[!showShared_(networkProperties_, globalPolicy,
+ hidden$="[[!showShared_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]">
$i18n{networkShared}
</div>
@@ -161,37 +165,37 @@
<template is="dom-if" if="[[!isSecondaryUser_]]">
<!-- Prefer this network. -->
<template is="dom-if"
- if="[[showPreferNetwork_(networkProperties_, globalPolicy,
+ if="[[showPreferNetwork_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]">
<div class="settings-box" on-click="onPreferNetworkRowClicked_"
actionable$="[[!isNetworkPolicyEnforced(
- networkProperties_.Priority)]]">
+ managedProperties_.priority)]]">
<div id="preferNetworkToggleLabel" class="start settings-box-text">
$i18n{networkPrefer}
</div>
- <cr-policy-network-indicator
- property="[[networkProperties_.Priority]]">
- </cr-policy-network-indicator>
+ <cr-policy-network-indicator-mojo
+ property="[[managedProperties_.priority]]">
+ </cr-policy-network-indicator-mojo>
<cr-toggle id="preferNetworkToggle" checked="{{preferNetwork_}}"
disabled="[[isNetworkPolicyEnforced(
- networkProperties_.Priority)]]"
+ managedProperties_.priority)]]"
aria-labelledby="preferNetworkToggleLabel">
</cr-toggle>
</div>
</template>
<!-- Autoconnect. -->
<template is="dom-if"
- if="[[showAutoConnect_(networkProperties_, globalPolicy,
+ if="[[showAutoConnect_(managedProperties_, globalPolicy,
managedNetworkAvailable)]]">
<settings-toggle-button
id="autoConnectToggle"
- pref="{{autoConnect_}}"
- label="[[getAutoConnectToggleLabel_(networkProperties_)]]">
+ pref="{{autoConnectPref_}}"
+ label="[[getAutoConnectToggleLabel_(managedProperties_)]]">
</settings-toggle-button>
<!-- Hidden Network Warning -->
<template is="dom-if"
- if="[[showHiddenNetworkWarning_(autoConnect_.*,
- networkProperties_)]]"
+ if="[[showHiddenNetworkWarning_(autoConnectPref_.*,
+ managedProperties_)]]"
restamp>
<div class="warning">
<iron-icon icon="cr:warning"></iron-icon>
@@ -201,47 +205,48 @@
</template>
<!-- Always-on VPN. -->
<template is="dom-if"
- if="[[showAlwaysOnVpn_(networkProperties_)]]">
+ if="[[showAlwaysOnVpn_(managedProperties_)]]">
<settings-toggle-button id="alwaysOnVpnToggle"
pref="{{alwaysOnVpn_}}"
label="$i18n{networkAlwaysOnVpn}">
</settings-toggle-button>
</template>
<!-- Data roaming (Cellular only). -->
- <template is="dom-if" if="[[isCellular_(networkProperties_)]]">
+ <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
<settings-toggle-button id="allowDataRoaming"
pref="{{prefs.cros.signed.data_roaming_enabled}}"
label="$i18n{networkAllowDataRoaming}"
- sub-label="[[getRoamingDetails_(networkProperties_)]]">
+ sub-label="[[getRoamingDetails_(managedProperties_)]]">
</settings-toggle-button>
</template>
<!-- SIM Info (Cellular only). -->
- <template is="dom-if" if="[[showCellularSim_(networkProperties_)]]"
+ <template is="dom-if" if="[[showCellularSim_(managedProperties_)]]"
restamp>
<div class="settings-box single-column stretch">
- <network-siminfo on-siminfo-change="onNetworkPropertyChange_">
+ <network-siminfo device-state="[[deviceState_]]">
</network-siminfo>
</div>
</template>
<!-- IP Address. -->
<div class="settings-box two-line single-column stretch settings-box-text"
- hidden$="[[!showIpAddress_(ipAddress_, networkProperties_)]]">
+ hidden$="[[!showIpAddress_(ipAddress_, managedProperties_)]]">
<div>$i18n{networkIPAddress}</div>
<div class="secondary">[[ipAddress_]]</div>
</div>
<!-- Properties to always show if present. -->
- <template is="dom-if" if="[[hasInfoFields_(networkProperties_)]]">
+ <template is="dom-if" if="[[hasInfoFields_(managedProperties_)]]">
<div class="settings-box single-column stretch">
- <network-property-list
- fields="[[getInfoFields_(networkProperties_)]]"
- edit-field-types="[[getInfoEditFieldTypes_(networkProperties_)]]"
- property-dict="[[networkProperties_]]"
+ <network-property-list-mojo
+ fields="[[getInfoFields_(managedProperties_)]]"
+ edit-field-types="[[getInfoEditFieldTypes_(managedProperties_)]]"
+ property-dict="[[managedProperties_]]"
on-property-change="onNetworkPropertyChange_">
- </network-property-list>
+ </network-property-list-mojo>
</div>
</template>
- <template is="dom-if" if="[[showAdvanced_(networkProperties_)]]">
+ <template is="dom-if"
+ if="[[showAdvanced_(managedProperties_, propertiesReceived_)]]">
<!-- Advanced toggle. -->
<cr-expand-button
alt="$i18n{networkSectionAdvancedA11yLabel}"
@@ -253,24 +258,24 @@
<!-- Advanced section -->
<iron-collapse opened="[[advancedExpanded_]]">
<div class="settings-box single-column stretch indented first"
- hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties_)]]">
+ hidden$="[[!hasAdvancedOrDeviceFields_(managedProperties_)]]">
<!-- Advanced properties -->
- <network-property-list
- hidden$="[[!hasAdvancedFields_(networkProperties_)]]"
- fields="[[getAdvancedFields_(networkProperties_)]]"
- property-dict="[[networkProperties_]]">
- </network-property-list>
+ <network-property-list-mojo
+ hidden$="[[!hasAdvancedFields_(managedProperties_)]]"
+ fields="[[getAdvancedFields_(managedProperties_)]]"
+ property-dict="[[managedProperties_]]">
+ </network-property-list-mojo>
<!-- Device properties -->
- <network-property-list
- hidden$="[[!hasDeviceFields_(networkProperties_)]]"
- fields="[[getDeviceFields_(networkProperties_)]]"
- property-dict="[[networkProperties_]]">
- </network-property-list>
+ <network-property-list-mojo
+ hidden$="[[!hasDeviceFields_(managedProperties_)]]"
+ fields="[[getDeviceFields_(managedProperties_)]]"
+ property-dict="[[managedProperties_]]">
+ </network-property-list-mojo>
</div>
</iron-collapse>
</template>
- <template is="dom-if" if="[[hasNetworkSection_(networkProperties_,
+ <template is="dom-if" if="[[hasNetworkSection_(managedProperties_,
globalPolicy, managedNetworkAvailable)]]">
<!-- Network toggle -->
<cr-expand-button
@@ -282,7 +287,7 @@
$i18n{networkSectionNetwork}
</div>
<template is="dom-if"
- if="[[showScanningSpinner_(networkProperties_)]]">
+ if="[[showScanningSpinner_(managedProperties_, deviceState_)]]">
<paper-spinner-lite active></paper-spinner-lite>
</template>
</div>
@@ -292,35 +297,41 @@
<div class="settings-box single-column stretch indented first">
<!-- Choose Mobile Network (Cellular only). -->
<template is="dom-if"
- if="[[showCellularChooseNetwork_(networkProperties_)]]">
- <network-choose-mobile
- networking-private="[[networkingPrivate]]"
- network-properties="[[networkProperties_]]">
+ if="[[showCellularChooseNetwork_(managedProperties_)]]">
+ <network-choose-mobile device-state="[[deviceState_]]"
+ managed-properties="[[managedProperties_]]">
</network-choose-mobile>
</template>
<!-- APN -->
- <template is="dom-if" if="[[isCellular_(networkProperties_)]]">
- <network-apnlist on-apn-change="onNetworkPropertyChange_"
- network-properties="[[networkProperties_]]">
+ <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
+ <network-apnlist on-apn-change="onApnChange_"
+ managed-properties="[[managedProperties_]]">
</network-apnlist>
</template>
<!-- IP Config, Nameservers -->
<template is="dom-if"
- if="[[isRememberedOrConnected_(networkProperties_)]]">
+ if="[[isRememberedOrConnected_(managedProperties_)]]">
<network-ip-config on-ip-change="onIPConfigChange_"
- network-properties="[[networkProperties_]]">
+ managed-properties="[[managedProperties_]]">
</network-ip-config>
<network-nameservers on-nameservers-change="onIPConfigChange_"
- network-properties="[[networkProperties_]]">
+ managed-properties="[[managedProperties_]]">
</network-nameservers>
</template>
</div>
+
+ <!-- MAC Address. -->
+ <div class="settings-box two-line single-column stretch indented"
+ hidden$="[[!deviceState_.macAddress]]">
+ <div>$i18n{OncMacAddress}</div>
+ <div class="secondary">[[deviceState_.macAddress]]</div>
+ </div>
</iron-collapse>
</template>
- <template is="dom-if" if="[[hasProxySection_(networkProperties_,
+ <template is="dom-if" if="[[hasProxySection_(managedProperties_,
globalPolicy, managedNetworkAvailable)]]">
<!-- Proxy toggle -->
<cr-expand-button
@@ -333,17 +344,19 @@
<iron-collapse opened="[[proxyExpanded_]]">
<network-proxy-section prefs="{{prefs}}"
on-proxy-change="onProxyChange_"
- network-properties="[[networkProperties_]]">
+ managed-properties="[[managedProperties_]]">
</network-proxy-section>
</iron-collapse>
</template>
</template>
- <tether-connection-dialog id="tetherDialog"
- network-properties="[[networkProperties_]]"
- on-tether-connect="onTetherConnect_"
- out-of-range="[[outOfRange_]]">
- </tether-connection-dialog>
+ <template is="dom-if" if="[[isTether_(managedProperties_)]]" restamp>
+ <tether-connection-dialog id="tetherDialog"
+ managed-properties="[[managedProperties_]]"
+ on-tether-connect="onTetherConnect_"
+ out-of-range="[[outOfRange_]]">
+ </tether-connection-dialog>
+ </template>
</template>
<script src="internet_detail_page.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js
index bf2d66f205c..3dd71d9ff20 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -17,7 +17,7 @@ Polymer({
behaviors: [
CrNetworkListenerBehavior,
- CrPolicyNetworkBehavior,
+ CrPolicyNetworkBehaviorMojo,
settings.RouteObserverBehavior,
I18nBehavior,
],
@@ -32,15 +32,16 @@ Polymer({
notify: true,
},
- /**
- * The current properties for the network matching |guid|. Note: This may
- * become set to |undefined| after it is initially set if the network is no
- * longer visible, so always test that it is set before accessing it.
- * @private {!CrOnc.NetworkProperties|undefined}
- */
- networkProperties_: {
+ /** @private {!chromeos.networkConfig.mojom.ManagedProperties|undefined} */
+ managedProperties_: {
+ type: Object,
+ observer: 'managedPropertiesChanged_',
+ },
+
+ /** @private {?OncMojo.DeviceStateProperties} */
+ deviceState_: {
type: Object,
- observer: 'networkPropertiesChanged_',
+ value: null,
},
/**
@@ -90,12 +91,8 @@ Polymer({
value: null,
},
- /** @type {!chrome.networkingPrivate.GlobalPolicy|undefined} */
- globalPolicy: {
- type: Object,
- value: null,
- observer: 'globalPolicyChanged_',
- },
+ /** @type {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */
+ globalPolicy: Object,
/**
* Whether a managed network is available in the visible network list.
@@ -116,9 +113,9 @@ Polymer({
* The network AutoConnect state as a fake preference object.
* @private {!chrome.settingsPrivate.PrefObject|undefined}
*/
- autoConnect_: {
+ autoConnectPref_: {
type: Object,
- observer: 'autoConnectChanged_',
+ observer: 'autoConnectPrefChanged_',
},
/**
@@ -180,8 +177,11 @@ Polymer({
observers: [
'updateAlwaysOnVpnPrefValue_(prefs.arc.vpn.always_on.*)',
- 'updateAlwaysOnVpnPrefEnforcement_(prefs.vpn_config_allowed.*)',
- 'autoConnectChanged_(autoConnect_.*)', 'alwaysOnVpnChanged_(alwaysOnVpn_.*)'
+ 'updateAlwaysOnVpnPrefEnforcement_(managedProperties_,' +
+ 'prefs.vpn_config_allowed.*)',
+ 'updateAutoConnectPref_(globalPolicy)',
+ 'autoConnectPrefChanged_(autoConnectPref_.*)',
+ 'alwaysOnVpnChanged_(alwaysOnVpn_.*)',
],
/** @private {boolean} */
@@ -192,12 +192,12 @@ Polymer({
* prevents setProperties from being called when setting default properties.
* @private {boolean}
*/
- networkPropertiesReceived_: false,
+ propertiesReceived_: false,
/**
* Set in currentRouteChanged() if the showConfigure URL query
* parameter is set to true. The dialog cannot be shown until the
- * network properties have been fetched in networkPropertiesChanged_().
+ * network properties have been fetched in managedPropertiesChanged_().
* @private {boolean}
*/
shouldShowConfigureWhenNetworkLoaded_: false,
@@ -209,16 +209,15 @@ Polymer({
* This UI will use both the networkingPrivate extension API and the
* networkConfig mojo API until we provide all of the required functionality
* in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api.
- * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy}
+ * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote}
*/
- networkConfigProxy_: null,
+ networkConfig_: null,
/** @override */
created: function() {
this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/**
@@ -241,28 +240,23 @@ Polymer({
this.shouldShowConfigureWhenNetworkLoaded_ =
queryParams.get('showConfigure') == 'true';
- const type = /** @type {!chrome.networkingPrivate.NetworkType} */ (
- queryParams.get('type')) ||
- CrOnc.Type.WI_FI;
+ const type = queryParams.get('type') || 'WiFi';
const name = queryParams.get('name') || type;
this.init(guid, type, name);
},
/**
* @param {string} guid
- * @param {!chrome.networkingPrivate.NetworkType} type
+ * @param {string} type
* @param {string} name
- * @private
*/
init: function(guid, type, name) {
this.guid = guid;
- // Set basic networkProperties until they are loaded.
- this.networkPropertiesReceived_ = false;
- this.networkProperties_ = {
- GUID: this.guid,
- Type: type,
- Name: {Active: name},
- };
+ // Set default properties until they are loaded.
+ this.propertiesReceived_ = false;
+ this.deviceState_ = null;
+ this.managedProperties_ = OncMojo.getDefaultManagedProperties(
+ OncMojo.getNetworkTypeFromString(type), this.guid, name);
this.didSetFocus_ = false;
this.getNetworkDetails_();
},
@@ -281,8 +275,8 @@ Polymer({
// Clear network properties before navigating away to ensure that a future
// navigation back to the details page does not show a flicker of
// incorrect text. See https://crbug.com/905986.
- this.networkProperties_ = undefined;
- this.networkPropertiesReceived_ = false;
+ this.managedProperties_ = undefined;
+ this.propertiesReceived_ = false;
settings.navigateToPreviousRoute();
});
@@ -293,64 +287,69 @@ Polymer({
* @param {!Array<OncMojo.NetworkStateProperties>} networks
*/
onActiveNetworksChanged: function(networks) {
- if (!this.guid || !this.networkProperties_) {
+ if (!this.guid || !this.managedProperties_) {
return;
}
// If the network was or is active, request an update.
- if (this.networkProperties_.ConnectionState !=
- CrOnc.ConnectionState.NOT_CONNECTED ||
+ if (this.managedProperties_.connectionState !=
+ mojom.ConnectionStateType.kNotConnected ||
networks.find(network => network.guid == this.guid)) {
this.getNetworkDetails_();
}
},
+ /**
+ * CrosNetworkConfigObserver impl
+ * @param {!chromeos.networkConfig.mojom.NetworkStateProperties} network
+ */
+ onNetworkStateChanged: function(network) {
+ if (!this.guid || !this.managedProperties_) {
+ return;
+ }
+ if (network.guid == this.guid) {
+ this.getNetworkDetails_();
+ }
+ },
+
/** CrosNetworkConfigObserver impl */
onNetworkStateListChanged: function() {
+ if (!this.guid || !this.managedProperties_) {
+ return;
+ }
this.checkNetworkExists_();
},
/** CrosNetworkConfigObserver impl */
onDeviceStateListChanged: function() {
- if (this.guid) {
- this.getNetworkDetails_();
+ if (!this.guid || !this.managedProperties_) {
+ return;
}
- },
-
- /**
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
- * @private
- */
- globalPolicyChanged_: function(globalPolicy) {
- this.updateAutoConnectPref_(
- !!(this.autoConnect_ && this.autoConnect_.value), globalPolicy);
+ this.getDeviceState_();
+ this.getNetworkDetails_();
},
/** @private */
- networkPropertiesChanged_: function() {
- if (!this.networkProperties_) {
+ managedPropertiesChanged_: function() {
+ if (!this.managedProperties_) {
return;
}
+ this.updateAutoConnectPref_();
- // Update autoConnect if it has changed. Default value is false.
- this.updateAutoConnectPref_(
- CrOnc.getAutoConnect(this.networkProperties_), this.globalPolicy);
-
- // Update preferNetwork if it has changed. Default value is false.
- const priority = /** @type {number} */ (
- CrOnc.getActiveValue(this.networkProperties_.Priority) || 0);
- const preferNetwork = priority > 0;
- if (preferNetwork != this.preferNetwork_) {
- this.preferNetwork_ = preferNetwork;
+ const priority = this.managedProperties_.priority;
+ if (priority) {
+ const preferNetwork = priority.activeValue > 0;
+ if (preferNetwork != this.preferNetwork_) {
+ this.preferNetwork_ = preferNetwork;
+ }
}
- // Set the IPAddress property to the IPV4 Address.
- const ipv4 =
- CrOnc.getIPConfigForType(this.networkProperties_, CrOnc.IPType.IPV4);
- this.ipAddress_ = (ipv4 && ipv4.IPAddress) || '';
+ // Set the IPAddress property to the IPv4 Address.
+ const ipv4 = OncMojo.getIPConfigForType(this.managedProperties_, 'IPv4');
+ this.ipAddress_ = (ipv4 && ipv4.ipAddress) || '';
// Update the detail page title.
- this.parentNode.pageTitle = CrOnc.getNetworkName(this.networkProperties_);
-
+ const networkName = OncMojo.getNetworkName(this.managedProperties_);
+ this.parentNode.pageTitle = networkName;
Polymer.dom.flush();
if (!this.didSetFocus_) {
@@ -364,49 +363,69 @@ Polymer({
}
if (this.shouldShowConfigureWhenNetworkLoaded_ &&
- this.networkProperties_.Tether) {
+ this.managedProperties_.type == mojom.NetworkType.kTether) {
// Set |this.shouldShowConfigureWhenNetworkLoaded_| back to false to
// ensure that the Tether dialog is only shown once.
this.shouldShowConfigureWhenNetworkLoaded_ = false;
- this.showTetherDialog_();
+ // Async call to ensure dialog is stamped.
+ setTimeout(() => this.showTetherDialog_());
}
},
/** @private */
- autoConnectChanged_: function() {
- if (!this.networkProperties_ || !this.guid) {
+ getDeviceState_: function() {
+ if (!this.managedProperties_) {
return;
}
- const onc = this.getEmptyNetworkProperties_();
- CrOnc.setTypeProperty(onc, 'AutoConnect', !!this.autoConnect_.value);
- this.setNetworkProperties_(onc);
+ const type = this.managedProperties_.type;
+ this.networkConfig_.getDeviceStateList().then(response => {
+ const devices = response.result;
+ this.deviceState_ = devices.find(device => device.type == type) || null;
+ });
+ },
+
+ /** @private */
+ autoConnectPrefChanged_: function() {
+ if (!this.propertiesReceived_) {
+ return;
+ }
+ const config = {};
+ config.autoConnect = {value: !!this.autoConnectPref_.value};
+ this.setMojoNetworkProperties_(config);
},
/**
* Updates auto-connect pref value.
- * @param {boolean} value
- * @param {!chrome.networkingPrivate.GlobalPolicy|undefined} globalPolicy
* @private
*/
- updateAutoConnectPref_: function(value, globalPolicy) {
+ updateAutoConnectPref_: function() {
+ if (!this.managedProperties_) {
+ return;
+ }
+ const autoConnect = OncMojo.getManagedAutoConnect(this.managedProperties_);
+ if (!autoConnect) {
+ return;
+ }
+
let enforcement;
let controlledBy;
-
- if (this.isAutoConnectEnforcedByPolicy(
- this.networkProperties_, globalPolicy)) {
+ if (autoConnect.enforced ||
+ (!!this.globalPolicy &&
+ !!this.globalPolicy.allowOnlyPolicyNetworksToAutoconnect)) {
enforcement = chrome.settingsPrivate.Enforcement.ENFORCED;
controlledBy = chrome.settingsPrivate.ControlledBy.DEVICE_POLICY;
}
- if (this.autoConnect_ && this.autoConnect_.value == value &&
- enforcement == this.autoConnect_.enforcement &&
- controlledBy == this.autoConnect_.controlledBy) {
+ if (this.autoConnectPref_ &&
+ this.autoConnectPref_.value == autoConnect.activeValue &&
+ enforcement == this.autoConnectPref_.enforcement &&
+ controlledBy == this.autoConnectPref_.controlledBy) {
return;
}
const newPrefValue = {
key: 'fakeAutoConnectPref',
- value: value,
+ value: autoConnect.activeValue,
type: chrome.settingsPrivate.PrefType.BOOLEAN,
};
if (enforcement) {
@@ -414,95 +433,83 @@ Polymer({
newPrefValue.controlledBy = controlledBy;
}
- this.autoConnect_ = newPrefValue;
+ this.autoConnectPref_ = newPrefValue;
},
/** @private */
preferNetworkChanged_: function() {
- if (!this.networkProperties_ || !this.guid) {
+ if (!this.propertiesReceived_) {
return;
}
- const onc = this.getEmptyNetworkProperties_();
- onc.Priority = this.preferNetwork_ ? 1 : 0;
- this.setNetworkProperties_(onc);
+ const config = {};
+ config.priority = {value: this.preferNetwork_ ? 1 : 0};
+ this.setMojoNetworkProperties_(config);
},
/** @private */
checkNetworkExists_: function() {
const filter = {
- networkType: CrOnc.Type.ALL,
- visible: true,
- configured: false
+ filter: mojom.FilterType.kVisible,
+ networkType: mojom.NetworkType.kAll,
+ limit: mojom.kNoLimit,
};
- this.networkingPrivate.getNetworks(filter, networks => {
- if (networks.find(network => network.GUID == this.guid)) {
+ this.networkConfig_.getNetworkState(this.guid).then(response => {
+ if (response.result) {
+ // Don't update the state, a change event will trigger the update.
return;
}
this.outOfRange_ = true;
- if (this.networkProperties_) {
+ if (this.managedProperties_) {
// Set the connection state since we won't receive an update for a non
// existent network.
- this.networkProperties_.ConnectionState =
- CrOnc.ConnectionState.NOT_CONNECTED;
+ this.managedProperties_.connectionState =
+ mojom.ConnectionStateType.kNotConnected;
}
});
},
- /**
- * Calls networkingPrivate.getProperties for this.guid.
- * @private
- */
+ /** @private */
getNetworkDetails_: function() {
assert(this.guid);
if (this.isSecondaryUser_) {
- this.networkConfigProxy_.getNetworkState(this.guid).then(response => {
+ this.networkConfig_.getNetworkState(this.guid).then(response => {
this.getStateCallback_(response.result);
});
} else {
- this.networkingPrivate.getManagedProperties(
- this.guid, this.getPropertiesCallback_.bind(this));
+ this.networkConfig_.getManagedProperties(this.guid).then(response => {
+ this.getPropertiesCallback_(response.result);
+ });
}
},
/**
- * networkingPrivate.getProperties callback.
- * @param {!CrOnc.NetworkProperties} properties The network properties.
+ * @param {?mojom.ManagedProperties} properties
* @private
*/
getPropertiesCallback_: function(properties) {
- if (chrome.runtime.lastError) {
- const message = chrome.runtime.lastError.message;
- if (message == 'Error.InvalidNetworkGuid') {
- console.error('Details page: GUID no longer exists: ' + this.guid);
- } else {
- console.error(
- 'Unexpected networkingPrivate.getManagedProperties error: ' +
- message + ' For: ' + this.guid);
- }
- this.close();
- return;
- }
-
// Details page was closed while request was in progress, ignore the result.
if (!this.guid) {
return;
}
if (!properties) {
- // Edge case, may occur when disabling. Close this.
+ console.error('Details page: GUID no longer exists: ' + this.guid);
this.close();
return;
}
+ this.managedProperties_ = properties;
// Detail page should not be shown when Arc VPN is not connected.
- if (this.isArcVpn_(properties) && !this.isConnectedState_(properties)) {
+ if (this.isArcVpn_(this.managedProperties_) &&
+ !this.isConnectedState_(this.managedProperties_)) {
this.guid = '';
this.close();
}
-
- this.networkProperties_ = properties;
- this.networkPropertiesReceived_ = true;
+ this.propertiesReceived_ = true;
this.outOfRange_ = false;
+ if (!this.deviceState_) {
+ this.getDeviceState_();
+ }
},
/**
@@ -515,57 +522,38 @@ Polymer({
this.close();
return;
}
- const type = /** @type {CrOnc.Type} */ (
- OncMojo.getNetworkTypeString(networkState.type));
-
- let connectionState;
- switch (networkState.connectionState) {
- case mojom.ConnectionStateType.kOnline:
- case mojom.ConnectionStateType.kConnected:
- case mojom.ConnectionStateType.kPortal:
- connectionState = CrOnc.ConnectionState.CONNECTED;
- break;
- case mojom.ConnectionStateType.kConnecting:
- connectionState = CrOnc.ConnectionState.CONNECTING;
- break;
- case mojom.ConnectionStateType.kNotConnected:
- connectionState = CrOnc.ConnectionState.NOT_CONNECTED;
- break;
- }
-
- this.networkProperties_ = {
- GUID: networkState.guid,
- Name: {Active: networkState.name},
- Type: type,
- Connectable: networkState.connectable,
- ConnectionState: connectionState,
- };
- this.networkPropertiesReceived_ = true;
+ const managedProperties = OncMojo.getDefaultManagedProperties(
+ networkState.type, networkState.guid, networkState.name);
+ managedProperties.connectable = networkState.connectable;
+ managedProperties.connectionState = networkState.connectionState;
+ this.managedProperties_ = managedProperties;
+
+ this.propertiesReceived_ = true;
this.outOfRange_ = false;
},
/**
- * @param {!CrOnc.NetworkProperties} properties
+ * @param {!mojom.ManagedProperties} properties
* @return {!OncMojo.NetworkStateProperties|undefined}
*/
getNetworkState_: function(properties) {
- return properties ? OncMojo.oncPropertiesToNetworkState(properties) :
- undefined;
+ if (!properties) {
+ return undefined;
+ }
+ return OncMojo.managedPropertiesToNetworkState(properties);
},
/**
- * @param {!chrome.networkingPrivate.NetworkConfigProperties} onc The ONC
- * network properties.
+ * @param {!mojom.ConfigProperties} config
* @private
*/
- setNetworkProperties_: function(onc) {
- if (!this.networkPropertiesReceived_) {
+ setMojoNetworkProperties_: function(config) {
+ if (!this.propertiesReceived_ || !this.guid) {
return;
}
-
- assert(this.guid);
- this.networkingPrivate.setProperties(this.guid, onc, () => {
- if (chrome.runtime.lastError) {
+ this.networkConfig_.setProperties(this.guid, config).then(response => {
+ if (!response.success) {
+ console.error('Unable to set properties: ' + JSON.stringify(config));
// An error typically indicates invalid input; request the properties
// to update any invalid fields.
this.getNetworkDetails_();
@@ -574,279 +562,338 @@ Polymer({
},
/**
- * @return {!chrome.networkingPrivate.NetworkConfigProperties} An ONC
- * dictionary with just the Type property set. Used for passing properties
- * to setNetworkProperties_.
- * @private
- */
- getEmptyNetworkProperties_: function() {
- const type = this.networkProperties_ ? this.networkProperties_.Type :
- CrOnc.Type.WI_FI;
- return {Type: type};
- },
-
- /**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {boolean} propertiesReceived
* @param {boolean} outOfRange
* @return {string} The text to display for the network connection state.
* @private
*/
- getStateText_: function(networkProperties, outOfRange) {
- if (!networkProperties || !networkProperties.ConnectionState) {
+ getStateText_: function(managedProperties, propertiesReceived, outOfRange) {
+ if (!managedProperties || !propertiesReceived) {
return '';
}
if (outOfRange) {
- return networkProperties.Type == CrOnc.Type.TETHER ?
+ return managedProperties.type == mojom.NetworkType.kTether ?
this.i18n('tetherPhoneOutOfRange') :
this.i18n('networkOutOfRange');
}
- return this.i18n('Onc' + networkProperties.ConnectionState);
+ if (managedProperties.type == mojom.NetworkType.kCellular &&
+ !managedProperties.connectable) {
+ if (managedProperties.cellular.homeProvider &&
+ managedProperties.cellular.homeProvider.name) {
+ return this.i18n(
+ 'cellularContactSpecificCarrier',
+ managedProperties.cellular.homeProvider.name);
+ }
+ return this.i18n('cellularContactDefaultCarrier');
+ }
+
+ return this.i18n(
+ OncMojo.getConnectionStateString(managedProperties.connectionState));
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string} The text to display for auto-connect toggle label.
* @private
*/
- getAutoConnectToggleLabel_: function(networkProperties) {
- return this.isCellular_(networkProperties) ?
+ getAutoConnectToggleLabel_: function(managedProperties) {
+ return this.isCellular_(managedProperties) ?
this.i18n('networkAutoConnectCellular') :
this.i18n('networkAutoConnect');
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string} The text to display with roaming details.
* @private
*/
- getRoamingDetails_: function(networkProperties) {
- if (!networkProperties.Cellular.AllowRoaming) {
+ getRoamingDetails_: function(managedProperties) {
+ if (!this.isCellular_(managedProperties)) {
+ return '';
+ }
+ if (!managedProperties.cellular.allowRoaming) {
return this.i18n('networkAllowDataRoamingDisabled');
}
- return networkProperties.Cellular.RoamingState ===
- CrOnc.RoamingState.ROAMING ?
+ return managedProperties.cellular.roamingState == 'Roaming' ?
this.i18n('networkAllowDataRoamingEnabledRoaming') :
this.i18n('networkAllowDataRoamingEnabledHome');
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties|undefined} managedProperties
* @return {boolean} True if the network is connected.
* @private
*/
- isConnectedState_: function(networkProperties) {
- return !!networkProperties &&
- networkProperties.ConnectionState == CrOnc.ConnectionState.CONNECTED;
+ isConnectedState_: function(managedProperties) {
+ return !!managedProperties &&
+ OncMojo.connectionStateIsConnected(managedProperties.connectionState);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties|undefined} managedProperties
+ * @param {boolean} outOfRange
+ * @return {boolean} True if the network shown cannot initiate a connection.
+ * @private
+ */
+ isConnectionErrorState_: function(managedProperties, outOfRange) {
+ if (outOfRange) {
+ return true;
+ }
+
+ if (!managedProperties) {
+ return false;
+ }
+
+ // It's still possible to initiate a connection to a network if it is not
+ // connectable as long as the network has an associated configuration flow.
+ // Cellular networks do not have a configuration flow, so a Cellular network
+ // that is not connectable represents an error state.
+ return managedProperties.type == mojom.NetworkType.kCellular &&
+ !managedProperties.connectable;
+ },
+
+ /**
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- isRemembered_: function(networkProperties) {
- const source = networkProperties ? networkProperties.Source : null;
- return !!source && source != CrOnc.Source.NONE;
+ isRemembered_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.source != mojom.OncSource.kNone;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- isRememberedOrConnected_: function(networkProperties) {
- return this.isRemembered_(networkProperties) ||
- this.isConnectedState_(networkProperties);
+ isRememberedOrConnected_: function(managedProperties) {
+ return this.isRemembered_(managedProperties) ||
+ this.isConnectedState_(managedProperties);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- isCellular_: function(networkProperties) {
- return !!networkProperties &&
- networkProperties.Type == CrOnc.Type.CELLULAR &&
- !!networkProperties.Cellular;
+ isCellular_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kCellular;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @return {boolean}
+ * @private
+ */
+ isTether_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kTether;
+ },
+
+ /**
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy|undefined} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
* @private
*/
isBlockedByPolicy_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (!networkProperties || networkProperties.Type != CrOnc.Type.WI_FI ||
- this.isPolicySource(networkProperties.Source) || !globalPolicy) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties || !globalPolicy ||
+ managedProperties.type != mojom.NetworkType.kWiFi ||
+ this.isPolicySource(managedProperties.source)) {
return false;
}
- return !!globalPolicy.AllowOnlyPolicyNetworksToConnect ||
- (!!globalPolicy.AllowOnlyPolicyNetworksToConnectIfAvailable &&
+ const hexSsid = OncMojo.getActiveString(managedProperties.wifi.hexSsid);
+ return !!globalPolicy.allowOnlyPolicyNetworksToConnect ||
+ (!!globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable &&
!!managedNetworkAvailable) ||
- (!!networkProperties.WiFi && !!networkProperties.WiFi.HexSSID &&
- !!globalPolicy.BlacklistedHexSSIDs &&
- globalPolicy.BlacklistedHexSSIDs.includes(
- CrOnc.getStateOrActiveString(networkProperties.WiFi.HexSSID)));
+ (!!hexSsid && !!globalPolicy.blockedHexSsids &&
+ globalPolicy.blockedHexSsids.includes(hexSsid));
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
* @private
*/
showConnect_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (!networkProperties) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties) {
return false;
}
if (this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable)) {
return false;
}
+
// TODO(lgcheng@) support connect Arc VPN from UI once Android support API
// to initiate a VPN session.
- if (this.isArcVpn_(networkProperties)) {
+ if (this.isArcVpn_(managedProperties)) {
return false;
}
-
- return networkProperties.Type != CrOnc.Type.ETHERNET &&
- networkProperties.ConnectionState ==
- CrOnc.ConnectionState.NOT_CONNECTED;
+ if (managedProperties.connectionState !=
+ mojom.ConnectionStateType.kNotConnected) {
+ return false;
+ }
+ // Cellular is not configurable, so we always show the connect button, and
+ // disable it if 'connectable' is false.
+ if (managedProperties.type == mojom.NetworkType.kCellular) {
+ return true;
+ }
+ // If 'connectable' is false we show the configure button.
+ return managedProperties.connectable &&
+ managedProperties.type != mojom.NetworkType.kEthernet;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showDisconnect_: function(networkProperties) {
- return !!networkProperties &&
- networkProperties.Type != CrOnc.Type.ETHERNET &&
- CrOnc.isConnectingOrConnected(networkProperties);
+ showDisconnect_: function(managedProperties) {
+ if (!managedProperties ||
+ managedProperties.type == mojom.NetworkType.kEthernet) {
+ return false;
+ }
+ return managedProperties.connectionState !=
+ mojom.ConnectionStateType.kNotConnected;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showForget_: function(networkProperties) {
- if (this.isSecondaryUser_ || !networkProperties) {
+ showForget_: function(managedProperties) {
+ if (!managedProperties || this.isSecondaryUser_) {
return false;
}
- const type = networkProperties.Type;
- if (type != CrOnc.Type.WI_FI && type != CrOnc.Type.VPN) {
+ const type = managedProperties.type;
+ if (type != mojom.NetworkType.kWiFi && type != mojom.NetworkType.kVPN) {
return false;
}
- if (this.isArcVpn_(networkProperties)) {
+ if (this.isArcVpn_(managedProperties)) {
return false;
}
- return !this.isPolicySource(networkProperties.Source) &&
- this.isRemembered_(networkProperties);
+ return !this.isPolicySource(managedProperties.source) &&
+ this.isRemembered_(managedProperties);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showActivate_: function(networkProperties) {
- if (this.isSecondaryUser_) {
+ showActivate_: function(managedProperties) {
+ if (!managedProperties || this.isSecondaryUser_) {
return false;
}
- if (!this.isCellular_(networkProperties)) {
+ if (!this.isCellular_(managedProperties)) {
return false;
}
- const activation = networkProperties.Cellular.ActivationState;
- return activation == CrOnc.ActivationState.NOT_ACTIVATED ||
- activation == CrOnc.ActivationState.PARTIALLY_ACTIVATED;
+ const activation = managedProperties.cellular.activationState;
+ return activation == mojom.ActivationStateType.kNotActivated ||
+ activation == mojom.ActivationStateType.kPartiallyActivated;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
* @private
*/
showConfigure_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (this.isSecondaryUser_ || !networkProperties) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties || this.isSecondaryUser_) {
return false;
}
if (this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable)) {
return false;
}
- const type = networkProperties.Type;
- if (type == CrOnc.Type.CELLULAR || type == CrOnc.Type.TETHER) {
+ const type = managedProperties.type;
+ if (type == mojom.NetworkType.kCellular ||
+ type == mojom.NetworkType.kTether) {
return false;
}
- if (type == CrOnc.Type.WI_FI) {
- const security = networkProperties.WiFi &&
- CrOnc.getActiveValue(networkProperties.WiFi.Security);
- if (!security || security == CrOnc.Security.NONE) {
- return false;
- }
+ if (type == mojom.NetworkType.kWiFi &&
+ managedProperties.wifi.security == mojom.SecurityType.kNone) {
+ return false;
}
- if ((type == CrOnc.Type.WI_FI || type == CrOnc.Type.WI_MAX) &&
- CrOnc.isConnectingOrConnected(networkProperties)) {
+ if (type == mojom.NetworkType.kWiFi &&
+ (managedProperties.connectionState !=
+ mojom.ConnectionStateType.kNotConnected)) {
return false;
}
- if (this.isArcVpn_(networkProperties) &&
- !this.isConnectedState_(networkProperties)) {
+ if (this.isArcVpn_(managedProperties) &&
+ !this.isConnectedState_(managedProperties)) {
return false;
}
return true;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.settingsPrivate.PrefObject} vpn_config_allowed
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!chrome.settingsPrivate.PrefObject} vpnConfigAllowed
* @return {boolean}
* @private
*/
- disableForget_: function(networkProperties, vpn_config_allowed) {
- return this.isVpn_(networkProperties) && vpn_config_allowed &&
- !vpn_config_allowed.value;
+ disableForget_: function(managedProperties, vpnConfigAllowed) {
+ if (!managedProperties) {
+ return true;
+ }
+ return managedProperties.type == mojom.NetworkType.kVPN &&
+ vpnConfigAllowed && !vpnConfigAllowed.value;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.settingsPrivate.PrefObject} vpn_config_allowed
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!chrome.settingsPrivate.PrefObject} vpnConfigAllowed
* @return {boolean}
* @private
*/
- disableConfigure_: function(networkProperties, vpn_config_allowed) {
- if (!networkProperties ||
- (this.isVpn_(networkProperties) && vpn_config_allowed &&
- !vpn_config_allowed.value)) {
+ disableConfigure_: function(managedProperties, vpnConfigAllowed) {
+ if (!managedProperties) {
return true;
}
- return this.isPolicySource(networkProperties.Source) &&
- !this.hasRecommendedFields_(networkProperties);
+ if (managedProperties.type == mojom.NetworkType.kVPN && vpnConfigAllowed &&
+ !vpnConfigAllowed.value) {
+ return true;
+ }
+ return this.isPolicySource(managedProperties.source) &&
+ !this.hasRecommendedFields_(managedProperties);
},
/**
- * @param {!Object} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
*/
- hasRecommendedFields_: function(networkProperties) {
- for (const property in networkProperties) {
- const propertyValue = networkProperties[property];
- if (this.isNetworkPolicyRecommended(propertyValue) ||
- (typeof propertyValue == 'object' &&
- this.hasRecommendedFields_(propertyValue))) {
+ hasRecommendedFields_: function(managedProperties) {
+ if (!managedProperties) {
+ return false;
+ }
+ for (const key of Object.keys(managedProperties)) {
+ const value = managedProperties[key];
+ if (typeof value != 'object' || value === null) {
+ continue;
+ }
+ if ('activeValue' in value) {
+ if (this.isNetworkPolicyRecommended(value)) {
+ return true;
+ }
+ } else if (this.hasRecommendedFields_(value)) {
return true;
}
}
@@ -854,34 +901,33 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showViewAccount_: function(networkProperties) {
- if (this.isSecondaryUser_) {
+ showViewAccount_: function(managedProperties) {
+ if (!managedProperties || this.isSecondaryUser_) {
return false;
}
// Show either the 'Activate' or the 'View Account' button (Cellular only).
- if (!this.isCellular_(networkProperties) ||
- this.showActivate_(networkProperties)) {
+ if (!this.isCellular_(managedProperties) ||
+ this.showActivate_(managedProperties)) {
return false;
}
- const paymentPortal = networkProperties.Cellular.PaymentPortal;
- if (!paymentPortal || !paymentPortal.Url) {
+ const paymentPortal = managedProperties.cellular.paymentPortal;
+ if (!paymentPortal || !paymentPortal.url) {
return false;
}
// Only show for connected networks or LTE networks with a valid MDN.
- if (!this.isConnectedState_(networkProperties)) {
- const technology = networkProperties.Cellular.NetworkTechnology;
- if (technology != CrOnc.NetworkTechnology.LTE &&
- technology != CrOnc.NetworkTechnology.LTE_ADVANCED) {
+ if (!this.isConnectedState_(managedProperties)) {
+ const technology = managedProperties.cellular.networkTechnology;
+ if (technology != 'LTE' && technology != 'LTEAdvanced') {
return false;
}
- if (!networkProperties.Cellular.MDN) {
+ if (!managedProperties.cellular.mdn) {
return false;
}
}
@@ -890,49 +936,37 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @param {?OncMojo.NetworkStateProperties} defaultNetwork
- * @param {boolean} networkPropertiesReceived
+ * @param {boolean} propertiesReceived
* @param {boolean} outOfRange
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean} Whether or not to enable the network connect button.
* @private
*/
enableConnect_: function(
- networkProperties, defaultNetwork, networkPropertiesReceived, outOfRange,
+ managedProperties, defaultNetwork, propertiesReceived, outOfRange,
globalPolicy, managedNetworkAvailable) {
if (!this.showConnect_(
- networkProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable)) {
return false;
}
- if (!networkPropertiesReceived || outOfRange) {
+ if (!propertiesReceived || outOfRange) {
return false;
}
- if (this.isSecondaryUser_ &&
- this.networkProperties_.Connectable === false) {
+ // Cellular networks are not configurable, so we show a disabled 'Connect'
+ // button when not connectable.
+ if (managedProperties.type == mojom.NetworkType.kCellular &&
+ !managedProperties.connectable) {
return false;
}
- if ((networkProperties.Type == CrOnc.Type.CELLULAR) &&
- (CrOnc.isSimLocked(networkProperties) ||
- this.get('Cellular.Scanning', networkProperties))) {
- return false;
- }
- if (networkProperties.Type == CrOnc.Type.VPN && !defaultNetwork) {
+ if (managedProperties.type == mojom.NetworkType.kVPN && !defaultNetwork) {
return false;
}
return true;
},
- /**
- * @param {!CrOnc.NetworkProperties=} networkProperties
- * @return {boolean} Whether or not we are looking at VPN configuration.
- * @private
- */
- isVpn_: function(networkProperties) {
- return !!networkProperties && networkProperties.Type == CrOnc.Type.VPN;
- },
-
/** @private */
updateAlwaysOnVpnPrefValue_: function() {
this.alwaysOnVpn_.value = this.prefs.arc && this.prefs.arc.vpn &&
@@ -953,14 +987,14 @@ Polymer({
// Only mark VPN networks as enforced. This fake pref also controls the
// policy indicator on the connect/disconnect buttons, so it shouldn't be
// shown on non-VPN networks.
- if (this.isVpn_(this.networkProperties_) && this.prefs &&
+ if (this.managedProperties_ &&
+ this.managedProperties_.type == mojom.NetworkType.kVPN && this.prefs &&
this.prefs.vpn_config_allowed && !this.prefs.vpn_config_allowed.value) {
fakeAlwaysOnVpnEnforcementPref.enforcement =
chrome.settingsPrivate.Enforcement.ENFORCED;
fakeAlwaysOnVpnEnforcementPref.controlledBy =
this.prefs.vpn_config_allowed.controlledBy;
}
-
return fakeAlwaysOnVpnEnforcementPref;
},
@@ -976,15 +1010,14 @@ Polymer({
* @private
*/
getTetherDialog_: function() {
- return /** @type {!TetherConnectionDialogElement} */ (this.$.tetherDialog);
+ return /** @type {!TetherConnectionDialogElement} */ (
+ this.$$('#tetherDialog'));
},
/** @private */
onConnectTap_: function() {
- // For Tether networks that have not connected to a host, show a dialog.
- if (this.networkProperties_.Type == CrOnc.Type.TETHER &&
- (!this.networkProperties_.Tether ||
- !this.networkProperties_.Tether.HasConnectedToHost)) {
+ if (this.managedProperties_.type == mojom.NetworkType.kTether &&
+ (!this.managedProperties_.tether.hasConnectedToHost)) {
this.showTetherDialog_();
return;
}
@@ -1002,9 +1035,9 @@ Polymer({
* @private
*/
fireNetworkConnect_: function(bypassDialog) {
- assert(this.networkProperties_);
+ assert(this.managedProperties_);
const networkState =
- OncMojo.oncPropertiesToNetworkState(this.networkProperties_);
+ OncMojo.managedPropertiesToNetworkState(this.managedProperties_);
this.fire(
'network-connect',
{networkState: networkState, bypassConnectionDialog: bypassDialog});
@@ -1012,7 +1045,11 @@ Polymer({
/** @private */
onDisconnectTap_: function() {
- this.networkingPrivate.startDisconnect(this.guid);
+ this.networkConfig_.startDisconnect(this.guid).then(response => {
+ if (!response.success) {
+ console.error('Disconnect failed for: ' + this.guid);
+ }
+ });
},
/** @private */
@@ -1024,29 +1061,29 @@ Polymer({
/** @private */
onActivateTap_: function() {
- this.networkingPrivate.startActivate(this.guid);
+ this.browserProxy_.showCellularSetupUI(this.guid);
},
/** @private */
onConfigureTap_: function() {
- if (this.networkProperties_ &&
- (this.isThirdPartyVpn_(this.networkProperties_) ||
- this.isArcVpn_(this.networkProperties_))) {
+ if (this.managedProperties_ &&
+ (this.isThirdPartyVpn_(this.managedProperties_) ||
+ this.isArcVpn_(this.managedProperties_))) {
this.browserProxy_.configureThirdPartyVpn(this.guid);
return;
}
this.fire('show-config', {
- guid: this.networkProperties_.GUID,
- type: this.networkProperties_.Type,
- name: CrOnc.getNetworkName(this.networkProperties_)
+ guid: this.guid,
+ type: OncMojo.getNetworkTypeString(this.managedProperties_.type),
+ name: OncMojo.getNetworkName(this.managedProperties_)
});
},
/** @private */
onViewAccountTap_: function() {
- // startActivate() will show the account page for activated networks.
- this.networkingPrivate.startActivate(this.guid);
+ // Currently 'Account Details' is the same as the activation UI.
+ this.browserProxy_.showCellularSetupUI(this.guid);
},
/** @type {string} */
@@ -1063,218 +1100,133 @@ Polymer({
*/
showHiddenNetworkWarning_: function() {
return loadTimeData.getBoolean('showHiddenNetworkWarning') &&
- !!this.autoConnect_ && !!this.autoConnect_.value &&
- !!this.networkProperties_ && !!this.networkProperties_.WiFi &&
- !!CrOnc.getActiveValue(this.networkProperties_.WiFi.HiddenSSID);
+ !!this.autoConnectPref_ && !!this.autoConnectPref_.value &&
+ !!this.managedProperties_ &&
+ !!this.managedProperties_.type == mojom.NetworkType.kWiFi &&
+ !!OncMojo.getActiveValue(this.managedProperties_.wifi.hiddenSsid);
},
/**
* Event triggered for elements associated with network properties.
* @param {!CustomEvent<!{
* field: string,
- * value: !CrOnc.NetworkPropertyType
+ * value: (string|number|boolean|!Array<string>)
* }>} e
* @private
*/
onNetworkPropertyChange_: function(e) {
- if (!this.networkProperties_) {
+ if (!this.propertiesReceived_) {
return;
}
const field = e.detail.field;
const value = e.detail.value;
- const onc = this.getEmptyNetworkProperties_();
- if (field == 'APN') {
- CrOnc.setTypeProperty(onc, 'APN', value);
- } else if (field == 'SIMLockStatus') {
- CrOnc.setTypeProperty(onc, 'SIMLockStatus', value);
- } else {
- const valueType = typeof value;
- if (valueType == 'string' || valueType == 'number' ||
- valueType == 'boolean' || Array.isArray(value)) {
- CrOnc.setProperty(onc, field, value);
- // Ensure any required configuration properties are also set.
- if (field.match(/^VPN/)) {
- const vpnType =
- CrOnc.getActiveValue(this.networkProperties_.VPN.Type);
- assert(vpnType);
- CrOnc.setProperty(onc, 'VPN.Type', vpnType);
- }
- } else {
- console.error(
- 'Unexpected property change event, Key: ' + field +
- ' Value: ' + JSON.stringify(value));
- return;
- }
+ const config = {};
+ const valueType = typeof value;
+ if (valueType != 'string' && valueType != 'number' &&
+ valueType != 'boolean' && !Array.isArray(value)) {
+ console.error(
+ 'Unexpected property change event, Key: ' + field +
+ ' Value: ' + JSON.stringify(value));
+ return;
}
- this.setNetworkProperties_(onc);
+ OncMojo.setConfigProperty(config, field, value);
+ // Ensure any required configuration properties are also set.
+ if (this.managedProperties_.vpn && config.vpn &&
+ config.vpn.type === undefined) {
+ config.vpn.type = this.managedProperties_.vpn.type;
+ }
+ this.setMojoNetworkProperties_(config);
},
/**
+ * @param {!CustomEvent<!mojom.ApnProperties>} event
+ * @private
+ */
+ onApnChange_: function(event) {
+ if (!this.propertiesReceived_) {
+ return;
+ }
+ const apn = event.detail;
+ const config = {cellular: {apn: apn}};
+ this.setMojoNetworkProperties_(config);
+ },
+
+
+ /**
* Event triggered when the IP Config or NameServers element changes.
* @param {!CustomEvent<!{
* field: string,
- * value: (string|!CrOnc.IPConfigProperties| !Array<string>)
+ * value: (string|!mojom.IPConfigProperties|!Array<string>)
* }>} event The network-ip-config or network-nameservers change event.
* @private
*/
onIPConfigChange_: function(event) {
- if (!this.networkProperties_) {
+ if (!this.managedProperties_) {
return;
}
- const field = event.detail.field;
- const value = event.detail.value;
- // Get an empty ONC dictionary and set just the IP Config properties that
- // need to change.
- const onc = this.getEmptyNetworkProperties_();
- const ipConfigType =
- /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ (
- CrOnc.getActiveValue(this.networkProperties_.IPAddressConfigType));
- if (field == 'IPAddressConfigType') {
- const newIpConfigType =
- /** @type {chrome.networkingPrivate.IPConfigType} */ (value);
- if (newIpConfigType == ipConfigType) {
- return;
- }
- onc.IPAddressConfigType = newIpConfigType;
- } else if (field == 'NameServersConfigType') {
- const nsConfigType =
- /** @type {chrome.networkingPrivate.IPConfigType|undefined} */ (
- CrOnc.getActiveValue(
- this.networkProperties_.NameServersConfigType));
- const newNsConfigType =
- /** @type {chrome.networkingPrivate.IPConfigType} */ (value);
- if (newNsConfigType == nsConfigType) {
- return;
- }
- onc.NameServersConfigType = newNsConfigType;
- } else if (field == 'StaticIPConfig') {
- if (ipConfigType == CrOnc.IPConfigType.STATIC) {
- const staticIpConfig = this.networkProperties_.StaticIPConfig;
- const ipConfigValue = /** @type {!Object} */ (value);
- if (staticIpConfig &&
- this.allPropertiesMatch_(staticIpConfig, ipConfigValue)) {
- return;
- }
- }
- onc.IPAddressConfigType = CrOnc.IPConfigType.STATIC;
- if (!onc.StaticIPConfig) {
- onc.StaticIPConfig =
- /** @type {!chrome.networkingPrivate.IPConfigProperties} */ ({});
- }
- // Only copy Static IP properties.
- const keysToCopy = ['Type', 'IPAddress', 'RoutingPrefix', 'Gateway'];
- for (let i = 0; i < keysToCopy.length; ++i) {
- const key = keysToCopy[i];
- if (key in value) {
- onc.StaticIPConfig[key] = value[key];
- }
- }
- } else if (field == 'NameServers') {
- // If a StaticIPConfig property is specified and its NameServers value
- // matches the new value, no need to set anything.
- const nameServers = /** @type {!Array<string>} */ (value);
- if (onc.NameServersConfigType == CrOnc.IPConfigType.STATIC &&
- onc.StaticIPConfig && onc.StaticIPConfig.NameServers == nameServers) {
- return;
- }
- onc.NameServersConfigType = CrOnc.IPConfigType.STATIC;
- if (!onc.StaticIPConfig) {
- onc.StaticIPConfig =
- /** @type {!chrome.networkingPrivate.IPConfigProperties} */ ({});
- }
- onc.StaticIPConfig.NameServers = nameServers;
- } else {
- console.error('Unexpected change field: ' + field);
- return;
+ const config = OncMojo.getUpdatedIPConfigProperties(
+ this.managedProperties_, event.detail.field, event.detail.value);
+ if (config) {
+ this.setMojoNetworkProperties_(config);
}
- // setValidStaticIPConfig will fill in any other properties from
- // networkProperties. This is necessary since we update IP Address and
- // NameServers independently.
- CrOnc.setValidStaticIPConfig(onc, this.networkProperties_);
- this.setNetworkProperties_(onc);
},
/**
* Event triggered when the Proxy configuration element changes.
- * @param {!CustomEvent<!{field: string, value: !CrOnc.ProxySettings}>} event
- * The network-proxy change event.
+ * @param {!CustomEvent<!mojom.ProxySettings>} event
* @private
*/
onProxyChange_: function(event) {
- if (!this.networkProperties_) {
- return;
- }
- const field = event.detail.field;
- const value = event.detail.value;
- if (field != 'ProxySettings') {
+ if (!this.propertiesReceived_) {
return;
}
- const onc = this.getEmptyNetworkProperties_();
- CrOnc.setProperty(onc, 'ProxySettings', /** @type {!Object} */ (value));
- this.setNetworkProperties_(onc);
+ this.setMojoNetworkProperties_({proxySettings: event.detail});
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean} True if the shared message should be shown.
* @private
*/
showShared_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- return !!networkProperties &&
- (networkProperties.Source == 'Device' ||
- networkProperties.Source == 'DevicePolicy') &&
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ return !!managedProperties &&
+ (managedProperties.source == mojom.OncSource.kDevice ||
+ managedProperties.source == mojom.OncSource.kDevicePolicy) &&
!this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable);
+ managedProperties, globalPolicy, managedNetworkAvailable);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean} True if the AutoConnect checkbox should be shown.
* @private
*/
showAutoConnect_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- return !!networkProperties &&
- networkProperties.Type != CrOnc.Type.ETHERNET &&
- this.isRemembered_(networkProperties) &&
- !this.isArcVpn_(networkProperties) &&
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ return !!managedProperties &&
+ managedProperties.type != mojom.NetworkType.kEthernet &&
+ this.isRemembered_(managedProperties) &&
+ !this.isArcVpn_(managedProperties) &&
!this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable);
+ managedProperties, globalPolicy, managedNetworkAvailable);
},
/**
- * @param {!CrOnc.NetworkProperties=} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy=} globalPolicy
- * @return {boolean}
- * @private
- */
- isAutoConnectEnforcedByPolicy: function(networkProperties, globalPolicy) {
- if (!networkProperties || networkProperties.Type != CrOnc.Type.WI_FI) {
- return false;
- }
- if (this.isPolicySource(networkProperties.Source)) {
- return !this.isEditable(CrOnc.getManagedAutoConnect(networkProperties));
- }
- return !!globalPolicy &&
- !!globalPolicy.AllowOnlyPolicyNetworksToAutoconnect;
- },
-
- /**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean} Whether the toggle for the Always-on VPN feature is
* displayed.
* @private
*/
- showAlwaysOnVpn_: function(networkProperties) {
- return this.isArcVpn_(networkProperties) && this.prefs.arc &&
+ showAlwaysOnVpn_: function(managedProperties) {
+ return this.isArcVpn_(managedProperties) && this.prefs.arc &&
this.prefs.arc.vpn && this.prefs.arc.vpn.always_on &&
this.prefs.arc.vpn.always_on.vpn_package &&
- networkProperties.VPN.Host.Active ===
+ OncMojo.getActiveValue(managedProperties.vpn.host) ===
this.prefs.arc.vpn.always_on.vpn_package.value;
},
@@ -1289,27 +1241,28 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean} True if the prefer network checkbox should be shown.
* @private
*/
showPreferNetwork_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (!networkProperties) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties) {
return false;
}
- const type = networkProperties.Type;
- if (type == CrOnc.Type.ETHERNET || type == CrOnc.Type.CELLULAR ||
- this.isArcVpn_(networkProperties)) {
+ const type = managedProperties.type;
+ if (type == mojom.NetworkType.kEthernet ||
+ type == mojom.NetworkType.kCellular ||
+ this.isArcVpn_(managedProperties)) {
return false;
}
- return this.isRemembered_(networkProperties) &&
+ return this.isRemembered_(managedProperties) &&
!this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable);
+ managedProperties, globalPolicy, managedNetworkAvailable);
},
/**
@@ -1336,7 +1289,7 @@ Polymer({
*/
hasVisibleFields_: function(fields) {
for (let i = 0; i < fields.length; ++i) {
- const value = this.get(fields[i], this.networkProperties_);
+ const value = this.get(fields[i], this.managedProperties_);
if (value !== undefined && value !== '') {
return true;
}
@@ -1358,65 +1311,70 @@ Polymer({
* @private
*/
getInfoFields_: function() {
- if (!this.networkProperties_) {
+ if (!this.managedProperties_) {
return [];
}
/** @type {!Array<string>} */ const fields = [];
- const type = this.networkProperties_.Type;
- if (type == CrOnc.Type.CELLULAR && !!this.networkProperties_.Cellular) {
- fields.push(
- 'Cellular.ActivationState', 'RestrictedConnectivity',
- 'Cellular.ServingOperator.Name');
- } else if (type == CrOnc.Type.TETHER && !!this.networkProperties_.Tether) {
+ const type = this.managedProperties_.type;
+ if (type == mojom.NetworkType.kCellular) {
+ fields.push('cellular.activationState', 'cellular.servingOperator.name');
+ if (this.managedProperties_.restrictedConnectivity) {
+ fields.push('restrictedConnectivity');
+ }
+ } else if (type == mojom.NetworkType.kTether) {
fields.push(
- 'Tether.BatteryPercentage', 'Tether.SignalStrength',
- 'Tether.Carrier');
- } else if (type == CrOnc.Type.VPN && !!this.networkProperties_.VPN) {
- const vpnType = CrOnc.getActiveValue(this.networkProperties_.VPN.Type);
+ 'tether.batteryPercentage', 'tether.signalStrength',
+ 'tether.carrier');
+ } else if (type == mojom.NetworkType.kVPN) {
+ const vpnType = this.managedProperties_.vpn.type;
switch (vpnType) {
- case CrOnc.VPNType.THIRD_PARTY_VPN:
- fields.push('VPN.ThirdPartyVPN.ProviderName');
+ case mojom.VpnType.kExtension:
+ fields.push('vpn.providerName');
break;
- case CrOnc.VPNType.ARCVPN:
- fields.push('VPN.Type');
+ case mojom.VpnType.kArc:
+ fields.push('vpn.type');
+ fields.push('vpn.providerName');
break;
- case CrOnc.VPNType.OPEN_VPN:
+ case mojom.VpnType.kOpenVPN:
fields.push(
- 'VPN.Type', 'VPN.Host', 'VPN.OpenVPN.Username',
- 'VPN.OpenVPN.ExtraHosts');
+ 'vpn.type', 'vpn.host', 'vpn.openVpn.username',
+ 'vpn.openVpn.extraHosts');
break;
- case CrOnc.VPNType.L2TP_IPSEC:
- fields.push('VPN.Type', 'VPN.Host', 'VPN.L2TP.Username');
+ case mojom.VpnType.kL2TPIPsec:
+ fields.push('vpn.type', 'vpn.host', 'vpn.l2tp.username');
break;
}
- } else if (type == CrOnc.Type.WI_FI) {
- fields.push('RestrictedConnectivity');
- } else if (type == CrOnc.Type.WI_MAX) {
- fields.push('RestrictedConnectivity', 'WiMAX.EAP.Identity');
+ } else if (type == mojom.NetworkType.kWiFi) {
+ if (this.managedProperties_.restrictedConnectivity) {
+ fields.push('restrictedConnectivity');
+ }
}
return fields;
},
/**
+ * Provides the list of editable fields to <network-property-list>.
+ * NOTE: Entries added to this list must be reflected in ConfigProperties in
+ * chromeos.network_config.mojom and handled in the service implementation.
* @return {!Object} A dictionary of editable fields in the info section.
* @private
*/
getInfoEditFieldTypes_: function() {
- if (!this.networkProperties_) {
+ if (!this.managedProperties_) {
return [];
}
/** @dict */ const editFields = {};
- const type = this.networkProperties_.Type;
- if (type == CrOnc.Type.VPN && !!this.networkProperties_.VPN) {
- const vpnType = CrOnc.getActiveValue(this.networkProperties_.VPN.Type);
- if (vpnType != CrOnc.VPNType.THIRD_PARTY_VPN) {
- editFields['VPN.Host'] = 'String';
+ const type = this.managedProperties_.type;
+ if (type == mojom.NetworkType.kVPN) {
+ const vpnType = this.managedProperties_.vpn.type;
+ if (vpnType != mojom.VpnType.kExtension) {
+ editFields['vpn.host'] = 'String';
}
- if (vpnType == CrOnc.VPNType.OPEN_VPN) {
- editFields['VPN.OpenVPN.Username'] = 'String';
- editFields['VPN.OpenVPN.ExtraHosts'] = 'StringArray';
+ if (vpnType == mojom.VpnType.kOpenVPN) {
+ editFields['vpn.openVpn.username'] = 'String';
+ editFields['vpn.openVpn.extraHosts'] = 'StringArray';
}
}
return editFields;
@@ -1427,26 +1385,21 @@ Polymer({
* @private
*/
getAdvancedFields_: function() {
- if (!this.networkProperties_) {
+ if (!this.managedProperties_) {
return [];
}
/** @type {!Array<string>} */ const fields = [];
- const type = this.networkProperties_.Type;
- if (type != CrOnc.Type.TETHER) {
- fields.push('MacAddress');
- }
- if (type == CrOnc.Type.CELLULAR && !!this.networkProperties_.Cellular) {
+ const type = this.managedProperties_.type;
+ if (type == mojom.NetworkType.kCellular) {
fields.push(
- 'Cellular.Family', 'Cellular.NetworkTechnology',
- 'Cellular.ServingOperator.Code');
- } else if (type == CrOnc.Type.WI_FI) {
+ 'cellular.family', 'cellular.networkTechnology',
+ 'cellular.servingOperator.code');
+ } else if (type == mojom.NetworkType.kWiFi) {
fields.push(
- 'WiFi.SSID', 'WiFi.BSSID', 'WiFi.SignalStrength', 'WiFi.Security',
- 'WiFi.EAP.Outer', 'WiFi.EAP.Inner', 'WiFi.EAP.SubjectMatch',
- 'WiFi.EAP.Identity', 'WiFi.EAP.AnonymousIdentity', 'WiFi.Frequency');
- } else if (type == CrOnc.Type.WI_MAX) {
- fields.push('WiFi.SignalStrength');
+ 'wifi.ssid', 'wifi.bssid', 'wifi.signalStrength', 'wifi.security',
+ 'wifi.eap.outer', 'wifi.eap.inner', 'wifi.eap.subjectMatch',
+ 'wifi.eap.identity', 'wifi.eap.anonymousIdentity', 'wifi.frequency');
}
return fields;
},
@@ -1456,34 +1409,36 @@ Polymer({
* @private
*/
getDeviceFields_: function() {
- if (!this.networkProperties_ ||
- this.networkProperties_.Type !== CrOnc.Type.CELLULAR) {
+ if (!this.managedProperties_ ||
+ this.managedProperties_.type !== mojom.NetworkType.kCellular) {
return [];
}
return [
- 'Cellular.HomeProvider.Name', 'Cellular.HomeProvider.Country',
- 'Cellular.HomeProvider.Code', 'Cellular.Manufacturer', 'Cellular.ModelID',
- 'Cellular.FirmwareRevision', 'Cellular.HardwareRevision', 'Cellular.ESN',
- 'Cellular.ICCID', 'Cellular.IMEI', 'Cellular.IMSI', 'Cellular.MDN',
- 'Cellular.MEID', 'Cellular.MIN', 'Cellular.PRLVersion'
+ 'cellular.homeProvider.name', 'cellular.homeProvider.country',
+ 'cellular.homeProvider.code', 'cellular.manufacturer', 'cellular.modelId',
+ 'cellular.firmwareRevision', 'cellular.hardwareRevision', 'cellular.esn',
+ 'cellular.iccid', 'cellular.imei', 'cellular.imsi', 'cellular.mdn',
+ 'cellular.meid', 'cellular.min'
];
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {boolean} propertiesReceived
* @return {boolean}
* @private
*/
- showAdvanced_: function(networkProperties) {
- if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) {
+ showAdvanced_: function(managedProperties, propertiesReceived) {
+ if (!managedProperties || !propertiesReceived) {
+ return false;
+ }
+ if (managedProperties.type == mojom.NetworkType.kTether) {
// These settings apply to the underlying WiFi network, not the Tether
// network.
return false;
}
- return this.hasAdvancedFields_() || this.hasDeviceFields_() ||
- (networkProperties.Type != CrOnc.Type.VPN &&
- this.isRememberedOrConnected_(networkProperties));
+ return this.hasAdvancedFields_() || this.hasDeviceFields_();
},
/**
@@ -1511,125 +1466,129 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
* @private
*/
hasNetworkSection_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties ||
+ managedProperties.type == mojom.NetworkType.kTether) {
// These settings apply to the underlying WiFi network, not the Tether
// network.
return false;
}
if (this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable)) {
return false;
}
- if (networkProperties.Type == CrOnc.Type.CELLULAR) {
+ if (managedProperties.type == mojom.NetworkType.kCellular) {
return true;
}
- return this.isRememberedOrConnected_(networkProperties);
+ return this.isRememberedOrConnected_(managedProperties);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.ManagedProperties} managedProperties
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
* @private
*/
hasProxySection_: function(
- networkProperties, globalPolicy, managedNetworkAvailable) {
- if (!networkProperties || networkProperties.Type == CrOnc.Type.TETHER) {
+ managedProperties, globalPolicy, managedNetworkAvailable) {
+ if (!managedProperties ||
+ managedProperties.type == mojom.NetworkType.kTether) {
// Proxy settings apply to the underlying WiFi network, not the Tether
// network.
return false;
}
if (this.isBlockedByPolicy_(
- networkProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable)) {
return false;
}
- return this.isRememberedOrConnected_(networkProperties);
+ return this.isRememberedOrConnected_(managedProperties);
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showCellularChooseNetwork_: function(networkProperties) {
- return !!networkProperties &&
- networkProperties.Type == CrOnc.Type.CELLULAR &&
- !!this.get('Cellular.SupportNetworkScan', this.networkProperties_);
+ showCellularChooseNetwork_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kCellular &&
+ managedProperties.cellular.supportNetworkScan;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
* @return {boolean}
* @private
*/
- showScanningSpinner_: function(networkProperties) {
- return !!this.get('Cellular.Scanning', networkProperties);
+ showScanningSpinner_: function() {
+ if (!this.managedProperties_ ||
+ this.managedProperties_.type != mojom.NetworkType.kCellular) {
+ return false;
+ }
+ return !!this.deviceState_ && this.deviceState_.scanning;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showCellularSim_: function(networkProperties) {
- return !!networkProperties &&
- networkProperties.Type == CrOnc.Type.CELLULAR &&
- !!networkProperties.Cellular &&
- networkProperties.Cellular.Family != 'CDMA';
+ showCellularSim_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kCellular &&
+ managedProperties.cellular.family != 'CDMA';
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties|undefined} managedProperties
* @return {boolean}
* @private
*/
- isArcVpn_: function(networkProperties) {
- return !!networkProperties && !!networkProperties.VPN &&
- CrOnc.getActiveValue(networkProperties.VPN.Type) ==
- CrOnc.VPNType.ARCVPN;
+ isArcVpn_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kVPN &&
+ managedProperties.vpn.type == mojom.VpnType.kArc;
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties|undefined} managedProperties
* @return {boolean}
* @private
*/
- isThirdPartyVpn_: function(networkProperties) {
- return !!networkProperties && !!networkProperties.VPN &&
- CrOnc.getActiveValue(networkProperties.VPN.Type) ==
- CrOnc.VPNType.THIRD_PARTY_VPN;
+ isThirdPartyVpn_: function(managedProperties) {
+ return !!managedProperties &&
+ managedProperties.type == mojom.NetworkType.kVPN &&
+ managedProperties.vpn.type == mojom.VpnType.kExtension;
},
/**
* @param {string} ipAddress
- * @param {!CrOnc.NetworkProperties} networkProperties
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- showIpAddress_: function(ipAddress, networkProperties) {
+ showIpAddress_: function(ipAddress, managedProperties) {
// Arc Vpn does not currently pass IP configuration to ChromeOS. IP address
// property holds an internal IP address Android uses to talk to ChromeOS.
// TODO(lgcheng@) Show correct IP address when we implement IP configuration
// correctly.
- if (this.isArcVpn_(networkProperties)) {
+ if (this.isArcVpn_(managedProperties)) {
return false;
}
// Cellular IP addresses are shown under the network details section.
- if (this.isCellular_(networkProperties)) {
+ if (this.isCellular_(managedProperties)) {
return false;
}
- return !!ipAddress && this.isConnectedState_(networkProperties);
+ return !!ipAddress && this.isConnectedState_(managedProperties);
},
/**
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
index 42dcf86aa71..b0d29715c33 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -5,7 +5,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-internet-known-networks-page">
@@ -36,10 +36,9 @@
<div class="list-item">
<cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
on-click="fireShowDetails_">
- <template is="dom-if" if="[[isPolicySourceMojo(item.source))]]">
+ <template is="dom-if" if="[[isPolicySource(item.source))]]">
<cr-policy-indicator on-click="doNothing_"
- indicator-type="[[getIndicatorTypeForSourceMojo(
- item.source)]]">
+ indicator-type="[[getIndicatorTypeForSource(item.source)]]">
</cr-policy-indicator>
</template>
</cr-link-row>
@@ -61,10 +60,9 @@
<div class="list-item">
<cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
on-click="fireShowDetails_">
- <template is="dom-if" if="[[isPolicySourceMojo(item.source))]]">
+ <template is="dom-if" if="[[isPolicySource(item.source))]]">
<cr-policy-indicator on-click="doNothing_"
- indicator-type="[[getIndicatorTypeForSourceMojo(
- item.source)]]">
+ indicator-type="[[getIndicatorTypeForSource(item.source)]]">
</cr-policy-indicator>
</template>
</cr-link-row>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
index 6d613efeda5..2e42c952c87 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
@@ -12,7 +12,7 @@ Polymer({
behaviors: [
CrNetworkListenerBehavior,
- CrPolicyNetworkBehavior,
+ CrPolicyNetworkBehaviorMojo,
],
properties: {
@@ -64,15 +64,14 @@ Polymer({
* This UI will use both the networkingPrivate extension API and the
* networkConfig mojo API until we provide all of the required functionality
* in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api.
- * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy}
+ * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote}
*/
- networkConfigProxy_: null,
+ networkConfig_: null,
/** @override */
created: function() {
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** CrosNetworkConfigObserver impl */
@@ -99,7 +98,7 @@ Polymer({
limit: chromeos.networkConfig.mojom.kNoLimit,
networkType: OncMojo.getNetworkTypeFromString(this.networkType),
};
- this.networkConfigProxy_.getNetworkStateList(filter).then(response => {
+ this.networkConfig_.getNetworkStateList(filter).then(response => {
this.networkStateList_ = response.result;
});
},
@@ -147,7 +146,7 @@ Polymer({
* @private
*/
getNetworkDisplayName_: function(networkState) {
- return OncMojo.getNetworkDisplayName(networkState);
+ return OncMojo.getNetworkStateDisplayName(networkState);
},
/**
@@ -162,14 +161,15 @@ Polymer({
// We need to make a round trip to Chrome in order to retrieve the managed
// properties for the network. The delay is not noticeable (~5ms) and is
// preferable to initiating a query for every known network at load time.
- this.networkingPrivate.getManagedProperties(
- this.selectedGuid_, properties => {
- if (chrome.runtime.lastError || !properties) {
- console.error(
- 'Unexpected error: ' + chrome.runtime.lastError.message);
+ this.networkConfig_.getManagedProperties(this.selectedGuid_)
+ .then(response => {
+ const properties = response.result;
+ if (!properties) {
+ console.error('Properties not found for: ' + this.selectedGuid_);
return;
}
- if (this.isNetworkPolicyEnforced(properties.Priority)) {
+ if (properties.priority &&
+ this.isNetworkPolicyEnforced(properties.priority)) {
this.showAddPreferred_ = false;
this.showRemovePreferred_ = false;
} else {
@@ -177,22 +177,37 @@ Polymer({
this.showAddPreferred_ = !preferred;
this.showRemovePreferred_ = preferred;
}
- this.enableForget_ = !this.isPolicySource(properties.Source);
+ this.enableForget_ = !this.isPolicySource(networkState.source);
/** @type {!CrActionMenuElement} */ (this.$.dotsMenu)
.showAt(/** @type {!Element} */ (button));
});
event.stopPropagation();
},
+ /**
+ * @param {!chromeos.networkConfig.mojom.ConfigProperties} config
+ * @private
+ */
+ setProperties_: function(config) {
+ this.networkConfig_.setProperties(this.selectedGuid_, config)
+ .then(response => {
+ if (!response.success) {
+ console.error(
+ 'Unable to set properties for: ' + this.selectedGuid_ + ': ' +
+ JSON.stringify(config));
+ }
+ });
+ },
+
/** @private */
onRemovePreferredTap_: function() {
- this.networkingPrivate.setProperties(this.selectedGuid_, {Priority: 0});
+ this.setProperties_({priority: {value: 0}});
/** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close();
},
/** @private */
onAddPreferredTap_: function() {
- this.networkingPrivate.setProperties(this.selectedGuid_, {Priority: 1});
+ this.setProperties_({priority: {value: 1}});
/** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close();
},
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
index 3727b4dad9a..10eeff05b0a 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -9,6 +9,7 @@
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="../i18n_setup.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../route.html">
<link rel="import" href="../settings_page/settings_animated_pages.html">
@@ -65,7 +66,7 @@
<cr-icon-button class$="[[getAddNetworkClass_('VPN')]]"
aria-label="$i18n{internetAddVPN}"></cr-icon-button>
</div>
- <template is="dom-repeat" items="[[thirdPartyVpnProviders_]]">
+ <template is="dom-repeat" items="[[vpnProviders_]]">
<div actionable class="list-item"
on-click="onAddThirdPartyVpnTap_">
<div class="start settings-box-text">
@@ -76,16 +77,6 @@
</cr-icon-button>
</div>
</template>
- <template is="dom-if" if="[[arcVpnProviders_.length]]">
- <div actionable class="list-item" id="addArcVpn"
- on-click="onAddArcVpnTap_">
- <div class="setting-box-text">
- $i18n{internetAddArcVPN}
- </div>
- <cr-icon-button class="icon-external"
- aria-label$="$i18n{internetAddArcVPN}"></cr-icon-button>
- </div>
- </template>
</div>
</template>
</template>
@@ -129,8 +120,7 @@
device-state="[[getDeviceState_(subpageType_, deviceStates)]]"
tether-device-state="[[getTetherDeviceState_(deviceStates)]]"
global-policy="[[globalPolicy_]]"
- third-party-vpn-providers="[[thirdPartyVpnProviders_]]"
- arc-vpn-providers="[[arcVpnProviders_]]"
+ vpn-providers="[[vpnProviders_]]"
show-spinner="{{showSpinner_}}">
</settings-internet-subpage>
</settings-subpage>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
index bb18ded6ab7..1737c822b40 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -15,6 +15,7 @@ Polymer({
is: 'settings-internet-page',
behaviors: [
+ CrNetworkListenerBehavior,
I18nBehavior,
settings.RouteObserverBehavior,
WebUIListenerBehavior,
@@ -84,11 +85,8 @@ Polymer({
value: false,
},
- /** @private {!chrome.networkingPrivate.GlobalPolicy|undefined} */
- globalPolicy_: {
- type: Object,
- value: null,
- },
+ /** @private {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */
+ globalPolicy_: Object,
/**
* Whether a managed network is available in the visible network list.
@@ -100,23 +98,11 @@ Polymer({
},
/**
- * List of third party VPN providers.
- * @type {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}
- * @private
- */
- thirdPartyVpnProviders_: {
- type: Array,
- value: function() {
- return [];
- }
- },
-
- /**
- * List of Arc VPN providers.
- * @type {!Array<!settings.ArcVpnProvider>}
+ * List of third party (Extension + Arc) VPN providers.
+ * @type {!Array<!chromeos.networkConfig.mojom.VpnProvider>}
* @private
*/
- arcVpnProviders_: {
+ vpnProviders_: {
type: Array,
value: function() {
return [];
@@ -145,16 +131,6 @@ Polymer({
'show-networks': 'onShowNetworks_',
},
- // chrome.management listeners
- /** @private {Function} */
- onExtensionAddedListener_: null,
-
- /** @private {Function} */
- onExtensionRemovedListener_: null,
-
- /** @private {Function} */
- onExtensionDisabledListener_: null,
-
/** @private {?settings.InternetPageBrowserProxy} */
browserProxy_: null,
@@ -162,58 +138,23 @@ Polymer({
* This UI will use both the networkingPrivate extension API and the
* networkConfig mojo API until we provide all of the required functionality
* in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api.
- * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy}
+ * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote}
*/
- networkConfigProxy_: null,
+ networkConfig_: null,
/** @override */
created: function() {
this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
- },
-
- /** @override */
- ready: function() {
- this.browserProxy_.setUpdateArcVpnProvidersCallback(
- this.onArcVpnProvidersReceived_.bind(this));
- this.browserProxy_.requestArcVpnProviders();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** @override */
attached: function() {
- this.onExtensionAddedListener_ =
- this.onExtensionAddedListener_ || this.onExtensionAdded_.bind(this);
- chrome.management.onInstalled.addListener(this.onExtensionAddedListener_);
- chrome.management.onEnabled.addListener(this.onExtensionAddedListener_);
-
- this.onExtensionRemovedListener_ =
- this.onExtensionRemovedListener_ || this.onExtensionRemoved_.bind(this);
- chrome.management.onUninstalled.addListener(
- this.onExtensionRemovedListener_);
-
- this.onExtensionDisabledListener_ = this.onExtensionDisabledListener_ ||
- this.onExtensionDisabled_.bind(this);
- chrome.management.onDisabled.addListener(this.onExtensionDisabledListener_);
-
- chrome.management.getAll(this.onGetAllExtensions_.bind(this));
-
- this.networkingPrivate.getGlobalPolicy(policy => {
- this.globalPolicy_ = policy;
+ this.networkConfig_.getGlobalPolicy().then(response => {
+ this.globalPolicy_ = response.result;
});
- },
-
- /** @override */
- detached: function() {
- chrome.management.onInstalled.removeListener(
- assert(this.onExtensionAddedListener_));
- chrome.management.onEnabled.removeListener(
- assert(this.onExtensionAddedListener_));
- chrome.management.onUninstalled.removeListener(
- assert(this.onExtensionRemovedListener_));
- chrome.management.onDisabled.removeListener(
- assert(this.onExtensionDisabledListener_));
+ this.onVpnProvidersChanged();
},
/**
@@ -278,6 +219,15 @@ Polymer({
}
},
+ /** CrosNetworkConfigObserver impl */
+ onVpnProvidersChanged: function() {
+ this.networkConfig_.getVpnProviders().then(response => {
+ const providers = response.providers;
+ providers.sort(this.compareVpnProviders_);
+ this.vpnProviders_ = providers;
+ });
+ },
+
/**
* Event triggered by a device state enabled toggle.
* @param {!CustomEvent<!{
@@ -287,7 +237,7 @@ Polymer({
* @private
*/
onDeviceEnabledToggled_: function(event) {
- this.networkConfigProxy_.setNetworkTypeEnabledState(
+ this.networkConfig_.setNetworkTypeEnabledState(
event.detail.type, event.detail.enabled);
},
@@ -336,7 +286,7 @@ Polymer({
const params = new URLSearchParams;
params.append('guid', networkState.guid);
params.append('type', oncType);
- params.append('name', OncMojo.getNetworkDisplayName(networkState));
+ params.append('name', OncMojo.getNetworkStateDisplayName(networkState));
settings.navigateTo(settings.routes.NETWORK_DETAIL, params);
},
@@ -454,19 +404,12 @@ Polymer({
},
/**
- * @param {!{model:
- * !{item: !chrome.networkingPrivate.ThirdPartyVPNProperties},
- * }} event
+ * @param {!{model: !{item: !mojom.VpnProvider}}} event
* @private
*/
onAddThirdPartyVpnTap_: function(event) {
const provider = event.model.item;
- this.browserProxy_.addThirdPartyVpn(provider.ExtensionID);
- },
-
- /** @private */
- onAddArcVpnTap_: function() {
- this.showNetworksSubpage_(mojom.NetworkType.kVPN);
+ this.browserProxy_.addThirdPartyVpn(provider.appId);
},
/**
@@ -483,101 +426,31 @@ Polymer({
},
/**
- * chrome.management.getAll callback.
- * @param {!Array<!chrome.management.ExtensionInfo>} extensions
- * @private
+ * @param {!mojom.VpnProvider} vpnProvider1
+ * @param {!mojom.VpnProvider} vpnProvider2
+ * @return {number}
*/
- onGetAllExtensions_: function(extensions) {
- const vpnProviders = [];
- for (let i = 0; i < extensions.length; ++i) {
- this.addVpnProvider_(vpnProviders, extensions[i]);
- }
- this.thirdPartyVpnProviders_ = vpnProviders;
- },
-
- /**
- * If |extension| is a third-party VPN provider, add it to |vpnProviders|.
- * @param {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}
- * vpnProviders
- * @param {!chrome.management.ExtensionInfo} extension
- * @private
- */
- addVpnProvider_: function(vpnProviders, extension) {
- if (!extension.enabled ||
- extension.permissions.indexOf('vpnProvider') == -1) {
- return;
- }
- if (vpnProviders.find(function(provider) {
- return provider.ExtensionID == extension.id;
- })) {
- return;
+ compareVpnProviders_: function(vpnProvider1, vpnProvider2) {
+ // Show Extension VPNs before Arc VPNs.
+ if (vpnProvider1.type < vpnProvider2.type) {
+ return -1;
}
- const newProvider = {
- ExtensionID: extension.id,
- ProviderName: extension.name,
- };
- vpnProviders.push(newProvider);
- },
-
- /**
- * chrome.management.onInstalled or onEnabled event.
- * @param {!chrome.management.ExtensionInfo} extension
- * @private
- */
- onExtensionAdded_: function(extension) {
- this.addVpnProvider_(this.thirdPartyVpnProviders_, extension);
- },
-
- /**
- * chrome.management.onUninstalled event.
- * @param {string} extensionId
- * @private
- */
- onExtensionRemoved_: function(extensionId) {
- for (let i = 0; i < this.thirdPartyVpnProviders_.length; ++i) {
- const provider = this.thirdPartyVpnProviders_[i];
- if (provider.ExtensionID == extensionId) {
- this.splice('thirdPartyVpnProviders_', i, 1);
- break;
- }
+ if (vpnProvider1.type > vpnProvider2.type) {
+ return 1;
}
- },
-
- /**
- * Compares Arc VPN Providers based on LastlauchTime
- * @param {!settings.ArcVpnProvider} arcVpnProvider1
- * @param {!settings.ArcVpnProvider} arcVpnProvider2
- * @private
- */
- compareArcVpnProviders_: function(arcVpnProvider1, arcVpnProvider2) {
- if (arcVpnProvider1.LastLaunchTime > arcVpnProvider2.LastLaunchTime) {
+ // Show VPNs of the same type by lastLaunchTime.
+ if (vpnProvider1.lastLaunchTime.internalValue >
+ vpnProvider2.lastLaunchTime.internalValue) {
return -1;
}
- if (arcVpnProvider1.LastLaunchTime < arcVpnProvider2.LastLaunchTime) {
+ if (vpnProvider1.lastLaunchTime.internalValue <
+ vpnProvider2.lastLaunchTime.internalValue) {
return 1;
}
return 0;
},
/**
- * @param {?Array<!settings.ArcVpnProvider>} arcVpnProviders
- * @private
- */
- onArcVpnProvidersReceived_: function(arcVpnProviders) {
- arcVpnProviders.sort(this.compareArcVpnProviders_);
- this.arcVpnProviders_ = arcVpnProviders;
- },
-
- /**
- * chrome.management.onDisabled event.
- * @param {{id: string}} extension
- * @private
- */
- onExtensionDisabled_: function(extension) {
- this.onExtensionRemoved_(extension.id);
- },
-
- /**
* @param {!Array<!OncMojo.DeviceStateProperties>} deviceStates
* @param {string} type
* @return {boolean}
@@ -591,7 +464,7 @@ Polymer({
},
/**
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
* @return {boolean}
*/
@@ -600,17 +473,17 @@ Polymer({
return true;
}
- return !globalPolicy.AllowOnlyPolicyNetworksToConnect &&
- (!globalPolicy.AllowOnlyPolicyNetworksToConnectIfAvailable ||
+ return !globalPolicy.allowOnlyPolicyNetworksToConnect &&
+ (!globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable ||
!managedNetworkAvailable);
},
/**
- * @param {!chrome.networkingPrivate.ThirdPartyVPNProperties} provider
+ * @param {!mojom.VpnProvider} provider
* @return {string}
*/
getAddThirdPartyVpnLabel_: function(provider) {
- return this.i18n('internetAddThirdPartyVPN', provider.ProviderName || '');
+ return this.i18n('internetAddThirdPartyVPN', provider.providerName || '');
},
/**
@@ -625,7 +498,7 @@ Polymer({
onNetworkConnect_: function(event) {
const networkState = event.detail.networkState;
const oncType = OncMojo.getNetworkTypeString(networkState.type);
- const displayName = OncMojo.getNetworkDisplayName(networkState);
+ const displayName = OncMojo.getNetworkStateDisplayName(networkState);
if (!event.detail.bypassConnectionDialog &&
networkState.type == mojom.NetworkType.kTether &&
@@ -647,24 +520,32 @@ Polymer({
return;
}
- this.networkingPrivate.startConnect(networkState.guid, () => {
- if (chrome.runtime.lastError) {
- const message = chrome.runtime.lastError.message;
- if (message == 'connecting' || message == 'connect-canceled' ||
- message == 'connected' || message == 'Error.InvalidNetworkGuid') {
+ this.networkConfig_.startConnect(networkState.guid).then(response => {
+ switch (response.result) {
+ case mojom.StartConnectResult.kSuccess:
+ return;
+ case mojom.StartConnectResult.kInvalidGuid:
+ case mojom.StartConnectResult.kInvalidState:
+ case mojom.StartConnectResult.kCanceled:
+ // TODO(stevenjb/khorimoto): Consider handling these cases.
+ return;
+ case mojom.StartConnectResult.kNotConfigured:
+ if (!isMobile) {
+ this.showConfig_(
+ true /* configAndConnect */, oncType, networkState.guid,
+ displayName);
+ }
+ return;
+ case mojom.StartConnectResult.kBlocked:
+ // This shouldn't happen, the UI should prevent this, fall through and
+ // show the error.
+ case mojom.StartConnectResult.kUnknown:
+ console.error(
+ 'startConnect failed for: ' + networkState.guid +
+ ' Error: ' + response.message);
return;
- }
- console.error(
- 'networkingPrivate.startConnect error: ' + message +
- ' For: ' + networkState.guid);
-
- // There is no configuration flow for Mobile Networks.
- if (!isMobile) {
- this.showConfig_(
- true /* configAndConnect */, oncType, networkState.guid,
- displayName);
- }
}
+ assertNotReached();
});
},
});
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/internet_page/internet_page_browser_proxy.js
index 42473ab988b..f39bf9141c8 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page_browser_proxy.js
@@ -5,20 +5,16 @@
/** @fileoverview A helper object used for Internet page. */
cr.exportPath('settings');
-/**
- * @typedef {{
- * PackageName: string,
- * ProviderName: string,
- * AppID: string,
- * LastLaunchTime: number,
- * }}
- */
-settings.ArcVpnProvider;
-
cr.define('settings', function() {
/** @interface */
class InternetPageBrowserProxy {
/**
+ * Shows the Cellular activation UI.
+ * @param {string} guid
+ */
+ showCellularSetupUI(guid) {}
+
+ /**
* Shows configuration for external VPNs. Includes ThirdParty (extension
* configured) VPNs, and Arc VPNs.
* @param {string} guid
@@ -33,18 +29,6 @@ cr.define('settings', function() {
addThirdPartyVpn(appId) {}
/**
- * Requests Chrome to send list of Arc VPN providers.
- */
- requestArcVpnProviders() {}
-
- /**
- * |callback| is run when there is update of Arc VPN providers.
- * Available after |requestArcVpnProviders| has been called.
- * @param {function(?Array<settings.ArcVpnProvider>):void} callback
- */
- setUpdateArcVpnProvidersCallback(callback) {}
-
- /**
* Requests that Chrome send the list of devices whose "Google Play
* Services" notifications are disabled (these notifications must be enabled
* to utilize Instant Tethering). The names will be provided via
@@ -67,6 +51,11 @@ cr.define('settings', function() {
*/
class InternetPageBrowserProxyImpl {
/** @override */
+ showCellularSetupUI(guid) {
+ chrome.send('showCellularSetupUI', [guid]);
+ }
+
+ /** @override */
configureThirdPartyVpn(guid) {
chrome.send('configureThirdPartyVpn', [guid]);
}
@@ -77,16 +66,6 @@ cr.define('settings', function() {
}
/** @override */
- requestArcVpnProviders() {
- chrome.send('requestArcVpnProviders');
- }
-
- /** @override */
- setUpdateArcVpnProvidersCallback(callback) {
- cr.addWebUIListener('sendArcVpnProviders', callback);
- }
-
- /** @override */
requestGmsCoreNotificationsDisabledDeviceNames() {
chrome.send('requestGmsCoreNotificationsDisabledDeviceNames');
}
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.html b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.html
index 3516ce9f4de..3307caa6c8e 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.html
@@ -5,12 +5,15 @@
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html">
<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="internet_page_browser_proxy.html">
+<link rel="import" href="../i18n_setup.html">
+<link rel="import" href="../route.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-internet-subpage">
@@ -154,16 +157,17 @@
<!-- Text shown if no networks exist. -->
<div hidden="[[shouldShowNetworkList_(networkStateList_)]]"
inner-h-t-m-l=
- "[[getNoNetworksString_(deviceState, tetherDeviceState)]]"
+ "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]"
class="no-networks">
</div>
<template is="dom-if" if="[[matchesType_('VPN', deviceState)]]">
<!-- Third party VPNs. -->
- <template is="dom-repeat" items="[[thirdPartyVpnProviders]]">
- <div id="[[item.ProviderName]]"
+ <template is="dom-repeat"
+ items="[[getVpnProviders_(vpnProviders, thirdPartyVpns_)]]">
+ <div id="[[item.providerName]]"
class="vpn-header layout horizontal center">
- <div class="flex settings-box-text">[[item.ProviderName]]</div>
+ <div class="flex settings-box-text">[[item.providerName]]</div>
<cr-icon-button class="icon-add-circle"
aria-label$="[[getAddThirdPartyVpnA11yString_(item)]]"
on-click="onAddThirdPartyVpnTap_" tabindex$="[[tabindex]]">
@@ -179,26 +183,6 @@
$i18n{internetNoNetworks}
</div>
</template>
- <!-- Arc VPNs. -->
- <template is="dom-repeat" items="[[arcVpnProviders]]">
- <div id="[[item.ProviderName]]"
- class="vpn-header layout horizontal center">
- <div class="flex settings-box-text">[[item.ProviderName]]</div>
- <cr-icon-button class="icon-add-circle"
- aria-label$="[[getAddArcVpnAllyString_(item)]]"
- on-click="onAddArcVpnTap_" tabindex$="[[tabindex]]">
- </cr-icon-button>
- </div>
- <cr-network-list show-buttons
- hidden$="[[!haveArcVpnNetwork_(arcVpns_, item)]]"
- networks="[[getArcVpnNetworks_(arcVpns_, item)]]"
- on-selected="onNetworkSelected_">
- </cr-network-list>
- <div hidden$="[[haveArcVpnNetwork_(arcVpns_, item)]]"
- class="no-networks">
- $i18n{internetNoNetworks}
- </div>
- </template>
</template>
</div>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js
index 0b5b7863c2f..9996d3b6538 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js
@@ -4,7 +4,7 @@
/**
* @fileoverview Polymer element for displaying information about WiFi,
- * WiMAX, or virtual networks.
+ * Cellular, or virtual networks.
*/
(function() {
@@ -16,7 +16,7 @@ Polymer({
behaviors: [
CrNetworkListenerBehavior,
- CrPolicyNetworkBehavior,
+ CrPolicyNetworkBehaviorMojo,
settings.RouteObserverBehavior,
I18nBehavior,
],
@@ -44,21 +44,14 @@ Polymer({
*/
tetherDeviceState: Object,
- /** @type {!chrome.networkingPrivate.GlobalPolicy|undefined} */
+ /** @type {!chromeos.networkConfig.mojom.GlobalPolicy|undefined} */
globalPolicy: Object,
/**
- * List of third party VPN providers.
- * @type
- * {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>|undefined}
+ * List of third party (Extension + Arc) VPN providers.
+ * @type {!Array<!chromeos.networkConfig.mojom.VpnProvider>}
*/
- thirdPartyVpnProviders: Array,
-
- /**
- * List of Arc VPN providers.
- * @type {!Array<!settings.ArcVpnProvider>|undefined}
- */
- arcVpnProviders: Array,
+ vpnProviders: Array,
showSpinner: {
type: Boolean,
@@ -89,17 +82,6 @@ Polymer({
},
/**
- * Dictionary of lists of network states for Arc VPNs.
- * @private {!Object<!Array<!OncMojo.NetworkStateProperties>>}
- */
- arcVpns_: {
- type: Object,
- value: function() {
- return {};
- }
- },
-
- /**
* List of potential Tether hosts whose "Google Play Services" notifications
* are disabled (these notifications are required to use Instant Tethering).
* @private {!Array<string>}
@@ -122,6 +104,12 @@ Polymer({
loadTimeData.getBoolean('showTechnologyBadge');
}
},
+
+ /** @private */
+ hasCompletedScanSinceLastEnabled_: {
+ type: Boolean,
+ value: false,
+ },
},
observers: ['deviceStateChanged_(deviceState)'],
@@ -136,16 +124,15 @@ Polymer({
* This UI will use both the networkingPrivate extension API and the
* networkConfig mojo API until we provide all of the required functionality
* in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api.
- * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy}
+ * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote}
*/
- networkConfigProxy_: null,
+ networkConfig_: null,
/** @override */
created: function() {
this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** @override */
@@ -170,32 +157,52 @@ Polymer({
this.stopScanning_();
return;
}
+ this.init();
+ },
+
+ init: function() {
// Clear any stale data.
this.networkStateList_ = [];
this.thirdPartyVpns_ = {};
- this.arcVpns_ = {};
+ this.hasCompletedScanSinceLastEnabled_ = false;
+ this.showSpinner = false;
+
// Request the list of networks and start scanning if necessary.
this.getNetworkStateList_();
this.updateScanning_();
},
/**
- * CrosNetworkConfigObserver impl
+ * CrNetworkListenerBehavior override
* @param {!Array<OncMojo.NetworkStateProperties>} networks
*/
onActiveNetworksChanged: function(networks) {
this.getNetworkStateList_();
},
- /** CrosNetworkConfigObserver impl */
+ /** CrNetworkListenerBehavior override */
onNetworkStateListChanged: function() {
this.getNetworkStateList_();
},
+ /** CrNetworkListenerBehavior override */
+ onVpnProvidersChanged: function() {
+ if (this.deviceState.type != mojom.NetworkType.kVPN) {
+ return;
+ }
+ this.getNetworkStateList_();
+ },
+
/** @private */
deviceStateChanged_: function() {
- this.showSpinner =
- this.deviceState !== undefined && !!this.deviceState.scanning;
+ if (this.deviceState !== undefined) {
+ // A scan has completed if the spinner was active (i.e., scanning was
+ // active) and the device is no longer scanning.
+ this.hasCompletedScanSinceLastEnabled_ = this.showSpinner &&
+ !this.deviceState.scanning &&
+ this.deviceState.deviceState == mojom.DeviceStateType.kEnabled;
+ this.showSpinner = !!this.deviceState.scanning;
+ }
// Scans should only be triggered by the "networks" subpage.
if (settings.getCurrentRoute() != settings.routes.INTERNET_NETWORKS) {
@@ -246,9 +253,9 @@ Polymer({
return;
}
const INTERVAL_MS = 10 * 1000;
- this.networkConfigProxy_.requestNetworkScan(this.deviceState.type);
+ this.networkConfig_.requestNetworkScan(this.deviceState.type);
this.scanIntervalId_ = window.setInterval(() => {
- this.networkConfigProxy_.requestNetworkScan(this.deviceState.type);
+ this.networkConfig_.requestNetworkScan(this.deviceState.type);
}, INTERVAL_MS);
},
@@ -271,7 +278,7 @@ Polymer({
limit: chromeos.networkConfig.mojom.kNoLimit,
networkType: this.deviceState.type,
};
- this.networkConfigProxy_.getNetworkStateList(filter).then(response => {
+ this.networkConfig_.getNetworkStateList(filter).then(response => {
this.onGetNetworks_(response.result);
});
},
@@ -294,48 +301,84 @@ Polymer({
limit: chromeos.networkConfig.mojom.kNoLimit,
networkType: mojom.NetworkType.kTether,
};
- this.networkConfigProxy_.getNetworkStateList(filter).then(response => {
+ this.networkConfig_.getNetworkStateList(filter).then(response => {
const tetherNetworkStates = response.result;
this.networkStateList_ = networkStates.concat(tetherNetworkStates);
});
return;
}
- // For VPNs, separate out third party VPNs and Arc VPNs.
+ // For VPNs, separate out third party (Extension + Arc) VPNs.
if (this.deviceState.type == mojom.NetworkType.kVPN) {
const builtinNetworkStates = [];
const thirdPartyVpns = {};
- const arcVpns = {};
networkStates.forEach(state => {
assert(state.type == mojom.NetworkType.kVPN);
switch (state.vpn.type) {
- case mojom.VPNType.kL2TPIPsec:
- case mojom.VPNType.kOpenVPN:
+ case mojom.VpnType.kL2TPIPsec:
+ case mojom.VpnType.kOpenVPN:
builtinNetworkStates.push(state);
break;
- case mojom.VPNType.kThirdPartyVPN:
- const providerName = state.vpn.providerName;
- thirdPartyVpns[providerName] = thirdPartyVpns[providerName] || [];
- thirdPartyVpns[providerName].push(state);
- break;
- case mojom.VPNType.kArcVPN:
- const arcProviderName = this.get('VPN.Host', state);
- if (OncMojo.connectionStateIsConnected(state.connectionState)) {
- arcVpns[arcProviderName] = arcVpns[arcProviderName] || [];
- arcVpns[arcProviderName].push(state);
+ case mojom.VpnType.kArc:
+ // Only show connected Arc VPNs.
+ if (!OncMojo.connectionStateIsConnected(state.connectionState)) {
+ break;
}
+ // Otherwise Arc VPNs are treated the same as Extension VPNs.
+ case mojom.VpnType.kExtension:
+ const providerId = state.vpn.providerId;
+ thirdPartyVpns[providerId] = thirdPartyVpns[providerId] || [];
+ thirdPartyVpns[providerId].push(state);
break;
}
});
networkStates = builtinNetworkStates;
this.thirdPartyVpns_ = thirdPartyVpns;
- this.arcVpns_ = arcVpns;
}
this.networkStateList_ = networkStates;
},
/**
+ * Returns an ordered list of VPN providers for all third party VPNs and any
+ * other known providers.
+ * @param {!Array<!chromeos.networkConfig.mojom.VpnProvider>} vpnProviders
+ * @param {!Object<!Array<!OncMojo.NetworkStateProperties>>} thirdPartyVpns
+ * @return {!Array<!chromeos.networkConfig.mojom.VpnProvider>}
+ * @private
+ */
+ getVpnProviders_(vpnProviders, thirdPartyVpns) {
+ // First add providers for configured thirdPartyVpns. This list will
+ // generally be empty or small.
+ const configuredProviders = [];
+ for (const vpnList of Object.values(thirdPartyVpns)) {
+ assert(vpnList.length > 0);
+ // All vpns in the list will have the same type and provider id.
+ const vpn = vpnList[0].vpn;
+ const provider = {
+ type: vpn.type,
+ providerId: vpn.providerId,
+ providerName: vpn.providerName || vpn.providerId,
+ appId: '',
+ lastLaunchTime: {internalValue: 0}
+ };
+ configuredProviders.push(provider);
+ }
+ // Next update or append known third party providers.
+ const unconfiguredProviders = [];
+ for (const provider of vpnProviders) {
+ const idx = configuredProviders.findIndex(
+ p => p.providerId == provider.providerId);
+ if (idx >= 0) {
+ configuredProviders[idx] = provider;
+ } else {
+ unconfiguredProviders.push(provider);
+ }
+ }
+ return configuredProviders.concat(unconfiguredProviders);
+ },
+
+ /**
* @param {!Array<string>} notificationsDisabledDeviceNames
* @private
*/
@@ -402,43 +445,32 @@ Polymer({
return this.i18n('internetToggleMobileA11yLabel');
case mojom.NetworkType.kWiFi:
return this.i18n('internetToggleWiFiA11yLabel');
- case mojom.NetworkType.kWiMAX:
- return this.i18n('internetToggleWiMAXA11yLabel');
}
assertNotReached();
return '';
},
/**
- * @param {!chrome.networkingPrivate.ThirdPartyVPNProperties} vpnState
- * @return {string}
- * @private
- */
- getAddThirdPartyVpnA11yString_: function(vpnState) {
- return this.i18n('internetAddThirdPartyVPN', vpnState.ProviderName || '');
- },
-
- /**
- * @param {!settings.ArcVpnProvider} arcVpn
+ * @param {!mojom.VpnProvider} provider
* @return {string}
* @private
*/
- getAddArcVpnAllyString_: function(arcVpn) {
- return this.i18n('internetAddArcVPNProvider', arcVpn.ProviderName);
+ getAddThirdPartyVpnA11yString_: function(provider) {
+ return this.i18n('internetAddThirdPartyVPN', provider.providerName || '');
},
/**
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @return {boolean}
* @private
*/
allowAddConnection_: function(globalPolicy) {
- return globalPolicy && !globalPolicy.AllowOnlyPolicyNetworksToConnect;
+ return globalPolicy && !globalPolicy.allowOnlyPolicyNetworksToConnect;
},
/**
* @param {!OncMojo.DeviceStateProperties|undefined} deviceState
- * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy
+ * @param {!mojom.GlobalPolicy} globalPolicy
* @return {boolean}
* @private
*/
@@ -461,22 +493,12 @@ Polymer({
},
/**
- * @param {!{model: !{item:
- * !chrome.networkingPrivate.ThirdPartyVPNProperties}}} event
+ * @param {!{model: !{item: !mojom.VpnProvider}}} event
* @private
*/
onAddThirdPartyVpnTap_: function(event) {
const provider = event.model.item;
- this.browserProxy_.addThirdPartyVpn(provider.ExtensionID);
- },
-
- /**
- * @param {!{model: !{item: !settings.ArcVpnProvider}}} event
- * @private
- */
- onAddArcVpnTap_: function(event) {
- const provider = event.model.item;
- this.browserProxy_.addThirdPartyVpn(provider.AppID);
+ this.browserProxy_.addThirdPartyVpn(provider.appId);
},
/**
@@ -512,43 +534,22 @@ Polymer({
/**
* @param {!Object<!Array<!OncMojo.NetworkStateProperties>>} thirdPartyVpns
- * @param {!chrome.networkingPrivate.ThirdPartyVPNProperties} vpnState
+ * @param {!mojom.VpnProvider} provider
* @return {!Array<!OncMojo.NetworkStateProperties>}
* @private
*/
- getThirdPartyVpnNetworks_: function(thirdPartyVpns, vpnState) {
- return thirdPartyVpns[vpnState.ProviderName] || [];
+ getThirdPartyVpnNetworks_: function(thirdPartyVpns, provider) {
+ return thirdPartyVpns[provider.providerId] || [];
},
/**
* @param {!Object<!Array<!OncMojo.NetworkStateProperties>>} thirdPartyVpns
- * @param {!chrome.networkingPrivate.ThirdPartyVPNProperties} vpnState
+ * @param {!mojom.VpnProvider} provider
* @return {boolean}
* @private
*/
- haveThirdPartyVpnNetwork_: function(thirdPartyVpns, vpnState) {
- const list = this.getThirdPartyVpnNetworks_(thirdPartyVpns, vpnState);
- return !!list.length;
- },
-
- /**
- * @param {!Object<!Array<!OncMojo.NetworkStateProperties>>} arcVpns
- * @param {!settings.ArcVpnProvider} arcVpnProvider
- * @return {!Array<!OncMojo.NetworkStateProperties>}
- * @private
- */
- getArcVpnNetworks_: function(arcVpns, arcVpnProvider) {
- return arcVpns[arcVpnProvider.PackageName] || [];
- },
-
- /**
- * @param {!Object<!Array<!OncMojo.NetworkStateProperties>>} arcVpns
- * @param {!settings.ArcVpnProvider} arcVpnProvider
- * @return {boolean}
- * @private
- */
- haveArcVpnNetwork_: function(arcVpns, arcVpnProvider) {
- const list = this.getArcVpnNetworks_(arcVpns, arcVpnProvider);
+ haveThirdPartyVpnNetwork_: function(thirdPartyVpns, provider) {
+ const list = this.getThirdPartyVpnNetworks_(thirdPartyVpns, provider);
return !!list.length;
},
@@ -562,7 +563,7 @@ Polymer({
assert(this.defaultNetwork !== undefined);
const networkState = e.detail;
e.target.blur();
- if (this.canConnect_(networkState)) {
+ if (this.canAttemptConnection_(networkState)) {
this.fire('network-connect', {networkState: networkState});
return;
}
@@ -576,22 +577,24 @@ Polymer({
*/
isBlockedByPolicy_: function(state) {
if (state.type != mojom.NetworkType.kWiFi ||
- this.isPolicySourceMojo(state.source) || !this.globalPolicy) {
+ this.isPolicySource(state.source) || !this.globalPolicy) {
return false;
}
- return !!this.globalPolicy.AllowOnlyPolicyNetworksToConnect ||
- (!!this.globalPolicy.AllowOnlyPolicyNetworksToConnectIfAvailable &&
+ return !!this.globalPolicy.allowOnlyPolicyNetworksToConnect ||
+ (!!this.globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable &&
!!this.deviceState && !!this.deviceState.managedNetworkAvailable) ||
- (!!this.globalPolicy.BlacklistedHexSSIDs &&
- this.globalPolicy.BlacklistedHexSSIDs.includes(state.wifi.hexSsid));
+ (!!this.globalPolicy.blockedHexSsids &&
+ this.globalPolicy.blockedHexSsids.includes(state.wifi.hexSsid));
},
/**
- * Determines whether or not a network state can be connected to.
+ * Determines whether or not it is possible to attempt a connection to the
+ * provided network (e.g., whether it's possible to connect or configure the
+ * network for connection).
* @param {!OncMojo.NetworkStateProperties} state The network state.
* @private
*/
- canConnect_: function(state) {
+ canAttemptConnection_: function(state) {
if (state.connectionState != mojom.ConnectionStateType.kNotConnected) {
return false;
}
@@ -604,6 +607,11 @@ Polymer({
this.defaultNetwork.connectionState))) {
return false;
}
+ // Cellular networks do not have a configuration flow, so it's not possible
+ // to attempt a connection if the network is not conncetable.
+ if (state.type == mojom.NetworkType.kCellular && !state.connectable) {
+ return false;
+ }
return true;
},
@@ -669,14 +677,27 @@ Polymer({
* @return {string}
* @private
*/
- getNoNetworksString_: function(deviceState, tetherDeviceState) {
+ getNoNetworksInnerHtml_: function(deviceState, tetherDeviceState) {
const type = deviceState.type;
if (type == mojom.NetworkType.kTether ||
(type == mojom.NetworkType.kCellular && this.tetherDeviceState)) {
return this.i18nAdvanced('internetNoNetworksMobileData');
}
- return this.i18n('internetNoNetworks');
+ if (type == mojom.NetworkType.kVPN) {
+ return this.i18n('internetNoNetworks');
+ }
+
+ // If a scan has not yet completed since the device was last enabled, it may
+ // be the case that scan results are still in the process of arriving, so
+ // display a message stating that scanning is in progress. If a scan has
+ // already completed and there are still no networks present, this implies
+ // that there has been sufficient time to find a network, so display a
+ // messages stating that there are no networks. See https://crbug.com/974169
+ // for more details.
+ return this.hasCompletedScanSinceLastEnabled_ ?
+ this.i18n('internetNoNetworks') :
+ this.i18n('networkScanningLabel');
},
/**
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html
index c1e7309b691..a061a6e92ab 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html
@@ -5,8 +5,8 @@
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_indicator_mojo.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
@@ -22,7 +22,7 @@
<template>
<style include="internet-shared cr-hidden-style iron-flex
iron-flex-alignment">
- cr-policy-network-indicator {
+ cr-policy-network-indicator-mojo {
margin-inline-end: 10px;
}
@@ -38,19 +38,19 @@
<!-- Policy indicator. Only one dom-if below will be shown. -->
<template is="dom-if"
- if="[[shouldShowNetworkPolicyIndicator_(networkProperties)]]">
+ if="[[shouldShowNetworkPolicyIndicator_(managedProperties)]]">
<div class="settings-box">
<div class="layout horizontal center">
- <cr-policy-network-indicator
- property="[[networkProperties.ProxySettings.Type]]"
+ <cr-policy-network-indicator-mojo
+ property="[[managedProperties.proxySettings.type]]"
no-extension-indicator>
- </cr-policy-network-indicator>
+ </cr-policy-network-indicator-mojo>
<div>$i18n{networkProxyEnforcedPolicy}</div>
</div>
</div>
</template>
<template is="dom-if"
- if="[[shouldShowExtensionIndicator_(networkProperties)]]">
+ if="[[shouldShowExtensionIndicator_(managedProperties)]]">
<div class="settings-box">
<extension-controlled-indicator
extension-id="[[prefs.proxy.extensionId]]"
@@ -62,8 +62,7 @@
<!-- Allow shared proxies -->
<settings-toggle-button id="allowShared" class="continuation indented"
- hidden$="[[!shouldShowAllowShared_(
- networkProperties.ProxySettings.Type)]]"
+ hidden$="[[!shouldShowAllowShared_(managedProperties.source)]]"
pref="{{prefs.settings.use_shared_proxies}}"
label="$i18n{networkProxyAllowShared}"
on-settings-boolean-control-change="onAllowSharedProxiesChange_"
@@ -72,7 +71,7 @@
<div class="settings-box single-column stretch continuation indented">
<network-proxy editable
- network-properties="[[networkProperties]]"
+ managed-properties="[[managedProperties]]"
use-shared-proxies="[[useSharedProxies_]]">
</network-proxy>
</div>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js
index ce61e4f85c9..3827c8cbf37 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js
@@ -7,23 +7,24 @@
* detail page. This element is responsible for setting 'Allow proxies for
* shared networks'.
*/
+(function() {
+'use strict';
+
+const mojom = chromeos.networkConfig.mojom;
+
Polymer({
is: 'network-proxy-section',
behaviors: [
- CrPolicyNetworkBehavior,
+ CrPolicyNetworkBehaviorMojo,
I18nBehavior,
PrefsBehavior,
settings.RouteObserverBehavior,
],
properties: {
- /**
- * The network properties dictionary containing the proxy properties to
- * display and modify.
- * @type {!CrOnc.NetworkProperties|undefined}
- */
- networkProperties: Object,
+ /** @private {!chromeos.networkConfig.mojom.ManagedProperties|undefined} */
+ managedProperties: Object,
/**
* Reflects prefs.settings.use_shared_proxies for data binding.
@@ -54,17 +55,17 @@ Polymer({
* @private
*/
isShared_: function() {
- return this.networkProperties.Source == 'Device' ||
- this.networkProperties.Source == 'DevicePolicy';
+ return this.managedProperties.source == mojom.OncSource.kDevice ||
+ this.managedProperties.source == mojom.OncSource.kDevicePolicy;
},
/**
- * @return {!CrOnc.ManagedProperty|undefined}
+ * @return {!OncMojo.ManagedProperty|undefined}
* @private
*/
getProxySettingsTypeProperty_: function() {
- return /** @type {!CrOnc.ManagedProperty|undefined} */ (
- this.get('ProxySettings.Type', this.networkProperties));
+ return /** @type {!OncMojo.ManagedProperty|undefined} */ (
+ this.get('proxySettings.type', this.managedProperties));
},
/**
@@ -98,7 +99,7 @@ Polymer({
},
/**
- * @param {!CrOnc.ManagedProperty} property
+ * @param {!OncMojo.ManagedProperty} property
* @return {boolean}
* @private
*/
@@ -148,3 +149,4 @@ Polymer({
this.$.allowShared.focus();
},
});
+})();
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary.html b/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
index 1dfcd0bccaf..2ceba972978 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.html
@@ -1,7 +1,6 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior.html">
<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
<link rel="import" href="network_summary_item.html">
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
index 70b08bde47c..ac6a45c2d31 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
@@ -4,7 +4,7 @@
/**
* @fileoverview Polymer element for displaying a summary of network states
- * by type: Ethernet, WiFi, Cellular, WiMAX, and VPN.
+ * by type: Ethernet, WiFi, Cellular, and VPN.
*/
(function() {
@@ -16,7 +16,6 @@ Polymer({
behaviors: [
CrNetworkListenerBehavior,
- CrPolicyNetworkBehavior,
],
properties: {
@@ -76,8 +75,8 @@ Polymer({
},
},
- /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy} */
- networkConfigProxy_: null,
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
+ networkConfig_: null,
/**
* Set of GUIDs identifying active networks, one for each type.
@@ -87,9 +86,8 @@ Polymer({
/** @override */
created: function() {
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** @override */
@@ -135,7 +133,7 @@ Polymer({
*/
getNetworkLists_: function() {
// First get the device states.
- this.networkConfigProxy_.getDeviceStateList().then(response => {
+ this.networkConfig_.getDeviceStateList().then(response => {
// Second get the network states.
this.getNetworkStates_(response.result);
});
@@ -154,7 +152,7 @@ Polymer({
limit: chromeos.networkConfig.mojom.kNoLimit,
networkType: mojom.NetworkType.kAll,
};
- this.networkConfigProxy_.getNetworkStateList(filter).then(response => {
+ this.networkConfig_.getNetworkStateList(filter).then(response => {
this.updateNetworkStates_(response.result, deviceStateList);
});
},
@@ -177,7 +175,6 @@ Polymer({
mojom.NetworkType.kWiFi,
mojom.NetworkType.kCellular,
mojom.NetworkType.kTether,
- mojom.NetworkType.kWiMAX,
mojom.NetworkType.kVPN,
];
@@ -223,8 +220,8 @@ Polymer({
for (const type of orderedNetworkTypes) {
const device = newDeviceStates[type];
if (!device) {
- continue;
- } // The technology for this device type is unavailable.
+ continue; // The technology for this device type is unavailable.
+ }
// If both 'Tether' and 'Cellular' technologies exist, merge the network
// lists and do not add an active network for 'Tether' so that there is
@@ -241,7 +238,7 @@ Polymer({
// types are enabled but no Cellular network exists (edge case).
const networkState =
this.getActiveStateForType_(activeNetworkStatesByType, type);
- if (networkState.source === undefined &&
+ if (networkState.source == mojom.OncSource.kNone &&
device.deviceState == mojom.DeviceStateType.kProhibited) {
// Prohibited technologies are enforced by the device policy.
networkState.source =
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html
index 7e6f3f9fbce..5b26c96577a 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html
@@ -6,6 +6,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_network_behavior_mojo.html">
<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
@@ -29,15 +30,9 @@
flex: auto;
}
- #networkTitleText {
- color: #333;
- font-weight: 500;
- }
-
#networkState {
color: var(--cr-secondary-text-color);
font-size: inherit;
- font-weight: 400;
}
</style>
<div id="outerBox" class="settings-box two-line">
@@ -60,12 +55,12 @@
</div>
<template is="dom-if" if="[[showSimInfo_(deviceState)]]" restamp>
- <network-siminfo on-click="doNothing_">
+ <network-siminfo device-state="[[deviceState]]" on-click="doNothing_">
</network-siminfo>
</template>
<template is="dom-if" if="[[showPolicyIndicator_(activeNetworkState)]]">
- <cr-policy-indicator indicator-type="[[getIndicatorTypeForSourceMojo(
+ <cr-policy-indicator indicator-type="[[getIndicatorTypeForSource(
activeNetworkState.source)]]" on-click="doNothing_">
</cr-policy-indicator>
</template>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js
index 326cf06dfa1..09cbcd3965e 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js
@@ -16,7 +16,10 @@ const mojom = chromeos.networkConfig.mojom;
Polymer({
is: 'network-summary-item',
- behaviors: [CrPolicyNetworkBehavior, I18nBehavior],
+ behaviors: [
+ CrPolicyNetworkBehaviorMojo,
+ I18nBehavior,
+ ],
properties: {
/**
@@ -24,7 +27,10 @@ Polymer({
* a device becomes unavailable.
* @type {!OncMojo.DeviceStateProperties|undefined}
*/
- deviceState: Object,
+ deviceState: {
+ type: Object,
+ notify: true,
+ },
/**
* If both Cellular and Tether technologies exist, we combine the
@@ -120,12 +126,11 @@ Polymer({
* @private
*/
getConnectionStateText_: function(networkState, deviceState) {
- if (!networkState) {
+ if (!networkState || !networkState.guid) {
return '';
}
const connectionState = networkState.connectionState;
- const name =
- networkState ? OncMojo.getNetworkDisplayName(networkState) : '';
+ const name = OncMojo.getNetworkStateDisplayName(networkState);
if (OncMojo.connectionStateIsConnected(connectionState)) {
return name;
}
@@ -150,7 +155,7 @@ Polymer({
return (activeNetworkState !== undefined &&
OncMojo.connectionStateIsConnected(
activeNetworkState.connectionState)) ||
- this.isPolicySourceMojo(activeNetworkState.source);
+ this.isPolicySource(activeNetworkState.source);
},
/**
@@ -181,8 +186,7 @@ Polymer({
return true;
}
const simLockType = deviceState.simLockStatus.lockType;
- return simLockType == CrOnc.LockType.PIN ||
- simLockType == CrOnc.LockType.PUK;
+ return simLockType == 'sim-pin' || simLockType == 'sim-puk';
},
/**
@@ -211,7 +215,6 @@ Polymer({
case mojom.NetworkType.kTether:
return true;
case mojom.NetworkType.kWiFi:
- case mojom.NetworkType.kWiMAX:
return deviceState.deviceState != mojom.DeviceStateType.kUninitialized;
case mojom.NetworkType.kCellular:
return deviceState.deviceState !=
@@ -248,8 +251,6 @@ Polymer({
return this.i18n('internetToggleMobileA11yLabel');
case mojom.NetworkType.kWiFi:
return this.i18n('internetToggleWiFiA11yLabel');
- case mojom.NetworkType.kWiMAX:
- return this.i18n('internetToggleWiMAXA11yLabel');
}
assertNotReached();
return '';
@@ -324,9 +325,10 @@ Polymer({
activeNetworkState, deviceState, networkStateList) {
if (!this.shouldShowSubpage_(deviceState, networkStateList)) {
if (activeNetworkState.guid) {
- return OncMojo.getNetworkDisplayName(activeNetworkState);
- } else if (networkStateList.length > 0) {
- return OncMojo.getNetworkDisplayName(networkStateList[0]);
+ return OncMojo.getNetworkStateDisplayName(activeNetworkState);
+ }
+ if (networkStateList.length > 0) {
+ return OncMojo.getNetworkStateDisplayName(networkStateList[0]);
}
}
return this.getNetworkTypeString_(deviceState.type);
diff --git a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
index 8e8b914c2e6..22d07f9ecb5 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
@@ -1,12 +1,11 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html">
-<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../route.html">
<link rel="import" href="../settings_shared_css.html">
@@ -75,35 +74,36 @@
</span>
<div id="host-device-container">
<!-- TODO(hsuregan): Add an a11y label. -->
- <iron-icon icon="[[getSignalStrengthIconName_(networkProperties)]]">
+ <iron-icon icon="[[getSignalStrengthIconName_(managedProperties)]]">
</iron-icon>
<div id="host-device-text-container">
<span id="host-device-text-name">
- [[getDeviceName_(networkProperties)]]
+ [[getDeviceName_(managedProperties)]]
</span>
<span id="host-device-text-battery" class="secondary">
- [[getBatteryPercentageString_(networkProperties)]]
+ [[getBatteryPercentageString_(managedProperties)]]
</span>
</div>
<div class="flex"></div>
<div id="host-device-lost-container" hidden$="[[!outOfRange]]">
- <iron-icon icon="settings:alert-device-out-of-range"></iron-icon>
+ <iron-icon icon="os-settings:alert-device-out-of-range">
+ </iron-icon>
$i18n{tetherPhoneOutOfRange}
</div>
</div>
<div id="tether-explanation">
- [[getExplanation_(networkProperties)]]
+ [[getExplanation_(managedProperties)]]
</div>
<div id="tether-carrier-warning">
$i18n{tetherConnectionCarrierWarning}
</div>
<div id="tether-description-title">
- [[getDescriptionTitle_(networkProperties)]]
+ [[getDescriptionTitle_(managedProperties)]]
</div>
<ul id="tether-description-list">
<li>$i18n{tetherConnectionDescriptionMobileData}</li>
- <li>[[getBatteryDescription_(networkProperties)]]</li>
- <li hidden$="[[!shouldShowDisconnectFromWifi_(networkProperties)]]">
+ <li>[[getBatteryDescription_(managedProperties)]]</li>
+ <li hidden$="[[!shouldShowDisconnectFromWifi_(managedProperties)]]">
$i18n{tetherConnectionDescriptionWiFi}
</li>
</ul>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js
index 775051fab29..5a7c6beff6f 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js
@@ -2,15 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-/**
- * @typedef {{
- * tetherHostDeviceName: string,
- * batteryPercentage: number,
- * connectionStrength: number,
- * isTetherHostCurrentlyOnWifi: boolean
- * }}
- */
-let TetherConnectionData;
+(function() {
+'use strict';
+
+const mojom = chromeos.networkConfig.mojom;
Polymer({
is: 'tether-connection-dialog',
@@ -18,13 +13,8 @@ Polymer({
behaviors: [I18nBehavior],
properties: {
- /**
- * The current properties for the network matching |guid|.
- * @type {!CrOnc.NetworkProperties|undefined}
- */
- networkProperties: {
- type: Object,
- },
+ /** @private {!chromeos.networkConfig.mojom.ManagedProperties|undefined} */
+ managedProperties: Object,
/**
* Whether the network has been lost (e.g., has gone out of range).
@@ -71,12 +61,11 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network
- * properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {boolean}
* @private
*/
- shouldShowDisconnectFromWifi_: function(networkProperties) {
+ shouldShowDisconnectFromWifi_: function(managedProperties) {
// TODO(khorimoto): Pipe through a new network property which describes
// whether the tether host is currently connected to a Wi-Fi network. Return
// whether it is here.
@@ -84,13 +73,13 @@ Polymer({
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string} The battery percentage integer value converted to a
* string. Note that this will not return a string with a "%" suffix.
* @private
*/
- getBatteryPercentageAsString_: function(networkProperties) {
- const percentage = this.get('Tether.BatteryPercentage', networkProperties);
+ getBatteryPercentageAsString_: function(managedProperties) {
+ const percentage = this.get('tether.batteryPercentage', managedProperties);
if (percentage === undefined) {
return '';
}
@@ -102,69 +91,70 @@ Polymer({
* Custom icons are used here instead of a <cr-network-icon> because this
* dialog uses a special color scheme.
*
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string} The name of the icon to be used to represent the network's
* signal strength.
*/
- getSignalStrengthIconName_: function(networkProperties) {
- let signalStrength = this.get('Tether.SignalStrength', networkProperties);
+ getSignalStrengthIconName_: function(managedProperties) {
+ let signalStrength = this.get('tether.signalStrength', managedProperties);
if (signalStrength === undefined) {
signalStrength = 4;
}
- return 'settings:signal-cellular-' +
+ return 'os-settings:signal-cellular-' +
Math.min(4, Math.max(signalStrength, 0)) + '-bar';
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string}
* @private
*/
- getDeviceName_: function(networkProperties) {
- return CrOnc.getNetworkName(networkProperties);
+ getDeviceName_: function(managedProperties) {
+ return managedProperties ? OncMojo.getNetworkName(managedProperties) : '';
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string}
* @private
*/
- getBatteryPercentageString_: function(networkProperties) {
+ getBatteryPercentageString_: function(managedProperties) {
return this.i18n(
'tetherConnectionBatteryPercentage',
- this.getBatteryPercentageAsString_(networkProperties));
+ this.getBatteryPercentageAsString_(managedProperties));
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string}
* @private
*/
- getExplanation_: function(networkProperties) {
+ getExplanation_: function(managedProperties) {
return this.i18n(
'tetherConnectionExplanation',
- CrOnc.getEscapedNetworkName(networkProperties));
+ HTMLEscape(OncMojo.getNetworkName(managedProperties)));
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string}
* @private
*/
- getDescriptionTitle_: function(networkProperties) {
+ getDescriptionTitle_: function(managedProperties) {
return this.i18n(
'tetherConnectionDescriptionTitle',
- CrOnc.getEscapedNetworkName(networkProperties));
+ HTMLEscape(OncMojo.getNetworkName(managedProperties)));
},
/**
- * @param {!CrOnc.NetworkProperties} networkProperties The network properties.
+ * @param {!mojom.ManagedProperties} managedProperties
* @return {string}
* @private
*/
- getBatteryDescription_: function(networkProperties) {
+ getBatteryDescription_: function(managedProperties) {
return this.i18n(
'tetherConnectionDescriptionBattery',
- this.getBatteryPercentageAsString_(networkProperties));
+ this.getBatteryPercentageAsString_(managedProperties));
},
});
+})();
diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
index a69c59b8e0c..657239a5971 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
+++ b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -117,6 +117,16 @@ Polymer({
* @type {!LanguagesPageVisibility}
*/
pageVisibility: Object,
+
+ // <if expr="chromeos">
+ /** @private */
+ isGuest_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('isGuest');
+ },
+ },
+ // </if>
},
// <if expr="not is_macosx">
@@ -185,6 +195,11 @@ Polymer({
* @private
*/
shouldShowDialogSeparator_: function() {
+ // <if expr="chromeos">
+ if (this.isGuest_) {
+ return false;
+ }
+ // </if>
return this.languages != undefined && this.languages.enabled.length > 1;
},
@@ -268,7 +283,7 @@ Polymer({
}
// The UI language choice doesn't persist for guests.
- if (loadTimeData.getBoolean('isGuest')) {
+ if (this.isGuest_) {
menu.querySelector('#uiLanguageItem').hidden = true;
}
},
@@ -346,6 +361,7 @@ Polymer({
});
return inputMethod ? inputMethod.displayName : '';
},
+
// </if>
// <if expr="chromeos or is_win">
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.html
index 12a3bc36e31..adc498c1f7d 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.html
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.html
@@ -1,5 +1,7 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<!-- Anyone using this behavior might be using the referenced icons. -->
+<link rel="import" href="../chromeos/os_icons.html">
<link rel="import" href="../i18n_setup.html">
<link rel="import" href="multidevice_constants.html">
<script src="multidevice_feature_behavior.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js
index d4468ab27e9..727822ca512 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_behavior.js
@@ -116,11 +116,11 @@ const MultiDeviceFeatureBehaviorImpl = {
getIconName: function(feature) {
switch (feature) {
case settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE:
- return 'settings:multidevice-better-together-suite';
+ return 'os-settings:multidevice-better-together-suite';
case settings.MultiDeviceFeature.MESSAGES:
- return 'settings:multidevice-messages';
+ return 'os-settings:multidevice-messages';
case settings.MultiDeviceFeature.SMART_LOCK:
- return 'settings:multidevice-smart-lock';
+ return 'os-settings:multidevice-smart-lock';
default:
return '';
}
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.js
index f0e57fa3a19..1b8b003a81c 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.js
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_feature_item.js
@@ -57,6 +57,11 @@ Polymer({
return;
}
- settings.navigateTo(this.subpageRoute, this.subpageRouteUrlSearchParams);
+ // Remove the search term when navigating to avoid potentially having any
+ // visible search term reappear at a later time. See
+ // https://crbug.com/989119.
+ settings.navigateTo(
+ this.subpageRoute, this.subpageRouteUrlSearchParams,
+ true /* opt_removeSearch */);
},
});
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js
index 8dc4cf217eb..fe69ece9bc2 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js
@@ -56,14 +56,13 @@ Polymer({
},
},
- /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy} */
- networkConfigProxy_: null,
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
+ networkConfig_: null,
/** @override */
created: function() {
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** @override */
@@ -87,7 +86,7 @@ Polymer({
if (!networks.find(network => network.guid == guid)) {
return;
}
- this.networkConfigProxy_.getNetworkState(guid).then(response => {
+ this.networkConfig_.getNetworkState(guid).then(response => {
if (response.result) {
this.activeNetworkState_ = response.result;
}
@@ -113,7 +112,7 @@ Polymer({
* @private
*/
updateTetherDeviceState_: function() {
- this.networkConfigProxy_.getDeviceStateList().then(response => {
+ this.networkConfig_.getDeviceStateList().then(response => {
const kTether = chromeos.networkConfig.mojom.NetworkType.kTether;
const deviceStates = response.result;
const deviceState =
@@ -143,7 +142,7 @@ Polymer({
limit: 1,
networkType: kTether,
};
- this.networkConfigProxy_.getNetworkStateList(filter).then(response => {
+ this.networkConfig_.getNetworkStateList(filter).then(response => {
const networks = response.result;
this.activeNetworkState_ =
networks[0] || OncMojo.getDefaultNetworkState(kTether);
diff --git a/chromium/chrome/browser/resources/settings/os_settings_resources.grd b/chromium/chrome/browser/resources/settings/os_settings_resources.grd
index 8ad9dd094f8..8338d49eb90 100644
--- a/chromium/chrome/browser/resources/settings/os_settings_resources.grd
+++ b/chromium/chrome/browser/resources/settings/os_settings_resources.grd
@@ -19,6 +19,159 @@
file="chromeos/os_a11y_page/os_a11y_page.html"
type="chrome_html"
allowexternalscript="true" />
+ <structure name="IDR_OS_SETTINGS_APPS_PAGE_JS"
+ file="chromeos/os_apps_page/os_apps_page.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APPS_PAGE_HTML"
+ file="chromeos/os_apps_page/os_apps_page.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_JS"
+ file="chromeos/os_apps_page/app_management_page/app_management_page.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_HTML"
+ file="chromeos/os_apps_page/app_management_page/app_management_page.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CONSTANTS_JS"
+ file="chromeos/os_apps_page/app_management_page/constants.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CONSTANTS_HTML"
+ file="chromeos/os_apps_page/app_management_page/constants.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_STORE_CLIENT_JS"
+ file="chromeos/os_apps_page/app_management_page/store_client.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_STORE_CLIENT_HTML"
+ file="chromeos/os_apps_page/app_management_page/store_client.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_STORE_JS"
+ file="chromeos/os_apps_page/app_management_page/store.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_STORE_HTML"
+ file="chromeos/os_apps_page/app_management_page/store.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ACTIONS_JS"
+ file="chromeos/os_apps_page/app_management_page/actions.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ACTIONS_HTML"
+ file="chromeos/os_apps_page/app_management_page/actions.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_ITEM_JS"
+ file="chromeos/os_apps_page/app_management_page/app_item.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_ITEM_HTML"
+ file="chromeos/os_apps_page/app_management_page/app_item.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_BROWSER_PROXY_JS"
+ file="chromeos/os_apps_page/app_management_page/browser_proxy.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_BROWSER_PROXY_HTML"
+ file="chromeos/os_apps_page/app_management_page/browser_proxy.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_FAKE_PAGE_HANDLER_JS"
+ file="chromeos/os_apps_page/app_management_page/fake_page_handler.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_MAIN_VIEW_JS"
+ file="chromeos/os_apps_page/app_management_page/main_view.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_MAIN_VIEW_HTML"
+ file="chromeos/os_apps_page/app_management_page/main_view.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_TYPES_JS"
+ file="chromeos/os_apps_page/app_management_page/types.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_UTIL_JS"
+ file="chromeos/os_apps_page/app_management_page/util.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_UTIL_HTML"
+ file="chromeos/os_apps_page/app_management_page/util.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_SHARED_STYLE_HTML"
+ file="chromeos/os_apps_page/app_management_page/shared_style.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_SHARED_VARS_HTML"
+ file="chromeos/os_apps_page/app_management_page/shared_vars.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_REDUCERS_JS"
+ file="chromeos/os_apps_page/app_management_page/reducers.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_REDUCERS_HTML"
+ file="chromeos/os_apps_page/app_management_page/reducers.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_API_LISTENER_JS"
+ file="chromeos/os_apps_page/app_management_page/api_listener.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_API_LISTENER_HTML"
+ file="chromeos/os_apps_page/app_management_page/api_listener.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_DOM_SWITCH_JS"
+ file="chromeos/os_apps_page/app_management_page/dom_switch.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_DOM_SWITCH_HTML"
+ file="chromeos/os_apps_page/app_management_page/dom_switch.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PWA_PERMISSION_VIEW_JS"
+ file="chromeos/os_apps_page/app_management_page/pwa_permission_view.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PWA_PERMISSION_VIEW_HTML"
+ file="chromeos/os_apps_page/app_management_page/pwa_permission_view.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_ITEM_JS"
+ file="chromeos/os_apps_page/app_management_page/permission_item.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_ITEM_HTML"
+ file="chromeos/os_apps_page/app_management_page/permission_item.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_TOGGLE_JS"
+ file="chromeos/os_apps_page/app_management_page/permission_toggle.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_TOGGLE_HTML"
+ file="chromeos/os_apps_page/app_management_page/permission_toggle.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PIN_TO_SHELF_ITEM_JS"
+ file="chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PIN_TO_SHELF_ITEM_HTML"
+ file="chromeos/os_apps_page/app_management_page/pin_to_shelf_item.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_TOGGLE_ROW_JS"
+ file="chromeos/os_apps_page/app_management_page/toggle_row.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_TOGGLE_ROW_HTML"
+ file="chromeos/os_apps_page/app_management_page/toggle_row.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_PERMISSION_VIEW_JS"
+ file="chromeos/os_apps_page/app_management_page/app_permission_view.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_PERMISSION_VIEW_HTML"
+ file="chromeos/os_apps_page/app_management_page/app_permission_view.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ARC_PERMISSION_VIEW_JS"
+ file="chromeos/os_apps_page/app_management_page/arc_permission_view.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ARC_PERMISSION_VIEW_HTML"
+ file="chromeos/os_apps_page/app_management_page/arc_permission_view.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CHROME_APP_PERMISSION_VIEW_JS"
+ file="chromeos/os_apps_page/app_management_page/chrome_app_permission_view.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CHROME_APP_PERMISSION_VIEW_HTML"
+ file="chromeos/os_apps_page/app_management_page/chrome_app_permission_view.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_JS"
+ file="chromeos/os_apps_page/app_management_page/router.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_HTML"
+ file="chromeos/os_apps_page/app_management_page/router.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ICONS_HTML"
+ file="chromeos/os_apps_page/app_management_page/icons.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_UNINSTALL_BUTTON_JS"
+ file="chromeos/os_apps_page/app_management_page/uninstall_button.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_UNINSTALL_BUTTON_HTML"
+ file="chromeos/os_apps_page/app_management_page/uninstall_button.html"
+ type="chrome_html" />
<structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_JS"
file="a11y_page/manage_a11y_page.js"
type="chrome_html" />
@@ -125,12 +278,6 @@
file="settings_page/settings_animated_pages.js"
type="chrome_html"
preprocess="true" />
- <structure name="IDR_OS_SETTINGS_PERSONALIZATION_BROWSER_PROXY_HTML"
- file="chromeos/personalization_page/personalization_browser_proxy.html"
- type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_PERSONALIZATION_BROWSER_PROXY_JS"
- file="chromeos/personalization_page/personalization_browser_proxy.js"
- type="chrome_html" />
<structure name="IDR_OS_SETTINGS_PERSONALIZATION_PAGE_HTML"
file="chromeos/personalization_page/personalization_page.html"
type="chrome_html"
@@ -394,6 +541,12 @@
<structure name="IDR_OS_SETTINGS_DEVICE_STORAGE_JS"
file="device_page/storage.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_ENTRY_HTML"
+ file="device_page/storage_external_entry.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_ENTRY_JS"
+ file="device_page/storage_external_entry.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_HTML"
file="device_page/storage_external.html"
type="chrome_html" />
@@ -456,6 +609,10 @@
file="icons.html"
type="chrome_html"
preprocess="true" />
+ <structure name="IDR_OS_SETTINGS_OS_ICONS"
+ file="chromeos/os_icons.html"
+ type="chrome_html"
+ preprocess="true" />
<structure name="IDR_OS_SETTINGS_POWERWASH_DIALOG_HTML"
file="chromeos/os_reset_page/os_powerwash_dialog.html"
type="chrome_html" />
@@ -468,11 +625,11 @@
<structure name="IDR_OS_SETTINGS_RESET_PAGE_JS"
file="chromeos/os_reset_page/os_reset_page.js"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_RESET_OS_PROXY_JS"
- file="chromeos/os_reset_page/reset_os_proxy.js"
+ <structure name="IDR_OS_SETTINGS_RESET_BROWSER_PROXY_JS"
+ file="chromeos/os_reset_page/os_reset_browser_proxy.js"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_RESET_OS_PROXY_HTML"
- file="chromeos/os_reset_page/reset_os_proxy.html"
+ <structure name="IDR_OS_SETTINGS_RESET_BROWSER_PROXY_HTML"
+ file="chromeos/os_reset_page/os_reset_browser_proxy.html"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_LANGUAGES_HTML"
file="languages_page/languages.html"
@@ -523,6 +680,12 @@
<structure name="IDR_OS_SETTINGS_MEDIA_PICKER_JS"
file="site_settings/media_picker.js"
type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_OS_TOOLBAR_JS"
+ file="chromeos/os_toolbar/os_toolbar.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_OS_TOOLBAR_HTML"
+ file="chromeos/os_toolbar/os_toolbar.html"
+ type="chrome_html" />
<structure name="IDR_OS_SETTINGS_PEOPLE_PAGE_HTML"
file="chromeos/os_people_page/os_people_page.html"
type="chrome_html"
@@ -950,12 +1113,6 @@
<structure name="IDR_OS_SETTINGS_ZOOM_LEVELS_JS"
file="site_settings/zoom_levels.js"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_HTML"
- file="app_management_page/app_management_page.html"
- type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_JS"
- file="app_management_page/app_management_page.js"
- type="chrome_html" />
<structure name="IDR_OS_SETTINGS_ANDROID_APPS_PAGE_HTML"
file="android_apps_page/android_apps_page.html"
type="chrome_html" />
@@ -1347,6 +1504,12 @@
type="chrome_html"
preprocess="true"
allowexternalscript="true" />
+ <structure name="IDR_OS_SETTINGS_WALLPAPER_BROWSER_PROXY_HTML"
+ file="appearance_page/wallpaper_browser_proxy.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_WALLPAPER_BROWSER_PROXY_JS"
+ file="appearance_page/wallpaper_browser_proxy.js"
+ type="chrome_html" />
</structures>
</release>
</grit>
diff --git a/chromium/chrome/browser/resources/settings/page_visibility.js b/chromium/chrome/browser/resources/settings/page_visibility.js
index fc8d51f2e10..6096033fafd 100644
--- a/chromium/chrome/browser/resources/settings/page_visibility.js
+++ b/chromium/chrome/browser/resources/settings/page_visibility.js
@@ -37,6 +37,7 @@ let PageVisibility;
let A11yPageVisibility;
/**
+ * TODO(crbug.com/950007): Remove setWallpaper after SplitSettings launch.
* @typedef {{
* bookmarksBar: boolean,
* homeButton: boolean,
@@ -98,6 +99,11 @@ cr.define('settings', function() {
let pageVisibility;
const showOSSettings = loadTimeData.getBoolean('showOSSettings');
+ const isAccountManagerEnabled =
+ loadTimeData.valueExists('isAccountManagerEnabled') &&
+ loadTimeData.getBoolean('isAccountManagerEnabled');
+ const isKerberosEnabled = loadTimeData.valueExists('isKerberosEnabled') &&
+ loadTimeData.getBoolean('isKerberosEnabled');
if (loadTimeData.getBoolean('isGuest')) {
// "if not chromeos" and "if chromeos" in two completely separate blocks
@@ -167,8 +173,8 @@ cr.define('settings', function() {
autofill: true,
people: {
lockScreen: showOSSettings,
- kerberosAccounts: showOSSettings,
- googleAccounts: showOSSettings,
+ kerberosAccounts: showOSSettings && isKerberosEnabled,
+ googleAccounts: showOSSettings && isAccountManagerEnabled,
manageUsers: showOSSettings,
},
onStartup: true,
diff --git a/chromium/chrome/browser/resources/settings/parental_controls_page/parental_controls_page.html b/chromium/chrome/browser/resources/settings/parental_controls_page/parental_controls_page.html
index 960c4f9f0db..3a55afc70c6 100644
--- a/chromium/chrome/browser/resources/settings/parental_controls_page/parental_controls_page.html
+++ b/chromium/chrome/browser/resources/settings/parental_controls_page/parental_controls_page.html
@@ -15,10 +15,6 @@
<dom-module id="settings-parental-controls-page">
<template>
<style include="settings-shared">
- #parental-controls-setup-section {
- padding-inline-start: 20px;
- }
-
cr-link-row {
--cr-section-padding: 0;
}
@@ -28,16 +24,12 @@
<cr-link-row on-click="handleFamilyLinkButtonClick_"
label="$i18n{parentalControlsPageTitle}"
sub-label="$i18n{parentalControlsPageViewSettingsLabel}"
- start-icon="cr20:kite"
external>
+ <iron-icon icon="cr20:kite" aria-hidden="true"></iron-icon>
</cr-link-row>
</template>
<template is="dom-if" if="[[!isChild_]]">
- <div>
- <iron-icon icon="cr20:kite"></iron-icon>
- </div>
- <div id="parental-controls-setup-section"
- class="start settings-box-text">
+ <div class="start settings-box-text">
<div>
$i18n{parentalControlsPageTitle}
</div>
diff --git a/chromium/chrome/browser/resources/settings/people_page/BUILD.gn b/chromium/chrome/browser/resources/settings/people_page/BUILD.gn
index 799bbfa9a5d..05645882e1b 100644
--- a/chromium/chrome/browser/resources/settings/people_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/people_page/BUILD.gn
@@ -222,7 +222,8 @@ js_library("profile_info_browser_proxy") {
js_library("setup_fingerprint_dialog") {
deps = [
":fingerprint_browser_proxy",
- "//ui/webui/resources/cr_elements/chromeos/fingerprint:cr_fingerprint_progress_arc",
+ "//ui/webui/resources/cr_elements/chromeos/cr_lottie:cr_lottie",
+ "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc",
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
diff --git a/chromium/chrome/browser/resources/settings/people_page/account_manager.html b/chromium/chrome/browser/resources/settings/people_page/account_manager.html
index b4687fedb68..3addbf6027c 100644
--- a/chromium/chrome/browser/resources/settings/people_page/account_manager.html
+++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.html
@@ -17,6 +17,10 @@
<dom-module id="settings-account-manager">
<template>
<style include="settings-shared iron-flex iron-flex-alignment">
+ :host {
+ --add-account-margin-top: 16px;
+ }
+
.profile-icon {
background: center / cover no-repeat;
border-radius: 20px;
@@ -40,16 +44,17 @@
margin-inline-start: 60px;
}
- cr-policy-indicator {
- margin-inline-end: 1em;
- }
-
#account-list-header {
padding-bottom: 8px;
}
+ cr-policy-indicator {
+ margin-inline-end: 1em;
+ margin-top: var(--add-account-margin-top);
+ }
+
#add-account-button {
- margin-top: 16px;
+ margin-top: var(--add-account-margin-top);
}
#add-account-icon {
diff --git a/chromium/chrome/browser/resources/settings/people_page/account_manager.js b/chromium/chrome/browser/resources/settings/people_page/account_manager.js
index c4364f4ea11..8613c1262a3 100644
--- a/chromium/chrome/browser/resources/settings/people_page/account_manager.js
+++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.js
@@ -169,8 +169,7 @@ Polymer({
* @private
*/
refreshAccounts_: function() {
- const includeImages = true;
- this.browserProxy_.getAccounts(includeImages).then(accounts => {
+ this.browserProxy_.getAccounts().then(accounts => {
this.set('accounts_', accounts);
});
},
diff --git a/chromium/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.js b/chromium/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.js
index 87826f732a5..b08b02268b5 100644
--- a/chromium/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/people_page/account_manager_browser_proxy.js
@@ -19,7 +19,7 @@ cr.exportPath('settings');
* unmigrated: boolean,
* fullName: string,
* email: string,
- * pic: (string|undefined),
+ * pic: string,
* organization: (string|undefined),
* }}
*/
@@ -30,11 +30,9 @@ cr.define('settings', function() {
class AccountManagerBrowserProxy {
/**
* Returns a Promise for the list of GAIA accounts held in AccountManager.
- * @param {boolean} includeImages Include the profile icon images in
- * settings.Account.pic field, which increases IPC data from the browser.
* @return {!Promise<!Array<settings.Account>>}
*/
- getAccounts(includeImages) {}
+ getAccounts() {}
/**
* Triggers the 'Add account' flow.
@@ -72,8 +70,8 @@ cr.define('settings', function() {
*/
class AccountManagerBrowserProxyImpl {
/** @override */
- getAccounts(includeImages) {
- return cr.sendWithPromise('getAccounts', includeImages);
+ getAccounts() {
+ return cr.sendWithPromise('getAccounts');
}
/** @override */
diff --git a/chromium/chrome/browser/resources/settings/people_page/fingerprint_list.js b/chromium/chrome/browser/resources/settings/people_page/fingerprint_list.js
index 92cfb70ecef..657e219e3dd 100644
--- a/chromium/chrome/browser/resources/settings/people_page/fingerprint_list.js
+++ b/chromium/chrome/browser/resources/settings/people_page/fingerprint_list.js
@@ -117,9 +117,10 @@ Polymer({
// Flash the background.
listItem.animate(
- {
- backgroundColor: ['var(--google-grey-300)', 'white'],
- },
+ [
+ {backgroundColor: ['var(--google-grey-300)']},
+ {backgroundColor: ['white']}
+ ],
FLASH_DURATION_MS);
});
},
diff --git a/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.html b/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.html
index da29870c4e8..66f41e87954 100644
--- a/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.html
+++ b/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.html
@@ -169,11 +169,9 @@
</cr-action-menu>
</div>
- <cr-toast id="account-removed-toast" duration="3000">
+ <cr-toast id="account-toast" duration="3000">
<!-- Gets displayed with black font without div and id :-/ -->
- <div id="account-removed-toast-label">
- $i18n{kerberosAccountsAccountRemovedTip}
- </div>
+ <div id="account-toast-label">[[accountToastText_]]</div>
</cr-toast>
<template is="dom-if" if="[[showAddAccountDialog_]]" restamp>
diff --git a/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.js b/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.js
index aec55ed61e7..4f45f060ed1 100644
--- a/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.js
+++ b/chromium/chrome/browser/resources/settings/people_page/kerberos_accounts.js
@@ -46,6 +46,12 @@ Polymer({
return loadTimeData.getBoolean('kerberosAddAccountsAllowed');
},
},
+
+ /** @private */
+ accountToastText_: {
+ type: String,
+ value: '',
+ },
},
/** @private {?settings.KerberosAccountsBrowserProxy} */
@@ -106,7 +112,12 @@ Polymer({
/** @private */
onAddAccountDialogClosed_: function() {
+ if (this.$$('kerberos-add-account-dialog').accountWasRefreshed) {
+ this.showToast_('kerberosAccountsAccountRefreshedTip');
+ }
+
this.showAddAccountDialog_ = false;
+
// In case it was opened by the 'Refresh now' action menu.
this.closeActionMenu_();
},
@@ -152,7 +163,7 @@ Polymer({
/** @type {!settings.KerberosAccount} */ (this.selectedAccount_))
.then(error => {
if (error == settings.KerberosErrorType.kNone) {
- this.$$('#account-removed-toast').show();
+ this.showToast_('kerberosAccountsAccountRemovedTip');
} else {
console.error('Unexpected error removing account: ' + error);
}
@@ -176,5 +187,15 @@ Polymer({
*/
onRefreshNowClick_: function() {
this.showAddAccountDialog_ = true;
+ },
+
+ /**
+ * Pops up a toast with localized text |label|.
+ * @param {string} label Name of the localized label string.
+ * @private
+ */
+ showToast_: function(label) {
+ this.accountToastText_ = this.i18n(label);
+ this.$$('#account-toast').show();
}
});
diff --git a/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.html b/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.html
index b6f3fd769cd..45f8f74a85a 100644
--- a/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.html
+++ b/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.html
@@ -28,15 +28,21 @@
margin-inline-start: 1em;
}
+ #credentials {
+ margin-top: 16px;
+ }
+
#credentials > *:not(:last-child) {
margin-bottom: var(--cr-form-field-bottom-spacing);
}
#general-error-container {
+ display: flex;
height: 56px;
}
#config-error-container {
+ display: flex;
height: 40px;
margin-top: 16px;
}
@@ -46,10 +52,6 @@
color: var(--settings-error-color);
}
- .inner-error-container {
- display: flex;
- }
-
iron-icon[icon='cr:error'] {
fill: var(--settings-error-color);
margin-inline-end: 8px;
@@ -74,13 +76,12 @@
$i18n{addKerberosAccountDescription}
</h2>
- <div id="general-error-container">
- <div class="inner-error-container"
- hidden="[[!showError_(generalErrorText_)]]">
- <iron-icon id="error-icon" icon="cr:error"></iron-icon>
- <div id="general-error-message">[[generalErrorText_]]</div>
- </div>
+ <div id="general-error-container"
+ hidden="[[!showError_(generalErrorText_)]]">
+ <iron-icon id="error-icon" icon="cr:error"></iron-icon>
+ <div id="general-error-message">[[generalErrorText_]]</div>
</div>
+
<div id="credentials">
<cr-input id="username" label="$i18n{kerberosUsername}"
value="{{username_}}" invalid="[[showError_(usernameErrorText_)]]"
@@ -143,12 +144,10 @@
spellcheck="false" disabled="[[isManaged_]]">
</settings-textarea>
- <div id="config-error-container">
- <div class="inner-error-container"
- hidden="[[!showError_(configErrorText_)]]">
- <iron-icon id="error-icon" icon="cr:error"></iron-icon>
- <div id="config-error-message">[[configErrorText_]]</div>
- </div>
+ <div id="config-error-container"
+ hidden="[[!showError_(configErrorText_)]]">
+ <iron-icon id="error-icon" icon="cr:error"></iron-icon>
+ <div id="config-error-message">[[configErrorText_]]</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.js b/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.js
index 295a14d087a..5bb16f8daf9 100644
--- a/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.js
+++ b/chromium/chrome/browser/resources/settings/people_page/kerberos_add_account_dialog.js
@@ -20,6 +20,15 @@ Polymer({
*/
presetAccount: Object,
+ /**
+ * Whether an existing |presetAccount| was successfully authenticated.
+ * Always false if |presetAccount| is null (new accounts).
+ */
+ accountWasRefreshed: {
+ type: Boolean,
+ value: false,
+ },
+
/** @private */
username_: {
type: String,
@@ -170,7 +179,11 @@ Polymer({
onAdd_: function() {
assert(!this.inProgress_);
this.inProgress_ = true;
- this.updateErrorMessages_(settings.KerberosErrorType.kNone);
+
+ // Keep the general error, wiping it might cause the error to disappear and
+ // immediately reappear, causing 2 resizings of the dialog.
+ this.usernameErrorText_ = '';
+ this.passwordErrorText_ = '';
// An empty password triggers the Kerberos daemon to use the remembered one.
const passwordToSubmit = this.useRememberedPassword_ ? '' : this.password_;
@@ -187,6 +200,7 @@ Polymer({
// Success case. Close dialog.
if (error == settings.KerberosErrorType.kNone) {
+ this.accountWasRefreshed = this.presetAccount != null;
this.$.addDialog.close();
return;
}
@@ -331,8 +345,8 @@ Polymer({
/**
* @param {!settings.KerberosConfigErrorCode} code Error code
- * @param {!string} errorLine Line where the error occurred
- * @return {!string} Localized error string that corresponds to code
+ * @param {string} errorLine Line where the error occurred
+ * @return {string} Localized error string that corresponds to code
* @private
*/
getConfigErrorString_: function(code, errorLine) {
@@ -363,8 +377,8 @@ Polymer({
/**
* Selects a line in a text area and scrolls to it.
* @param {!Element} textArea A textarea element
- * @param {!number} lineIndex 0-based index of the line to select
- * @return {!string} The line at lineIndex.
+ * @param {number} lineIndex 0-based index of the line to select
+ * @return {string} The line at lineIndex.
* @private
*/
selectAndScrollTo_: function(textArea, lineIndex) {
diff --git a/chromium/chrome/browser/resources/settings/people_page/lock_screen.html b/chromium/chrome/browser/resources/settings/people_page/lock_screen.html
index a2ce568a87d..56fa177dc1d 100644
--- a/chromium/chrome/browser/resources/settings/people_page/lock_screen.html
+++ b/chromium/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -66,12 +66,6 @@
label="$i18n{enableScreenlock}">
</settings-toggle-button>
- <settings-toggle-button id="enableLockScreenMediaKeys"
- hidden="[[!lockScreenMediaKeysPreferenceEnabled_]]"
- pref="{{prefs.ash.lock_screen_media_keys_enabled}}"
- label="$i18n{lockScreenMediaKeys}">
- </settings-toggle-button>
-
<template is="dom-if" if="[[quickUnlockEnabled_]]">
<div id="lockOptionsDiv">
<div class="settings-box">
diff --git a/chromium/chrome/browser/resources/settings/people_page/lock_screen.js b/chromium/chrome/browser/resources/settings/people_page/lock_screen.js
index 6780493980f..f0584fee7e4 100644
--- a/chromium/chrome/browser/resources/settings/people_page/lock_screen.js
+++ b/chromium/chrome/browser/resources/settings/people_page/lock_screen.js
@@ -130,19 +130,6 @@ Polymer({
readOnly: true,
},
- /**
- * Whether the lock screen media keys preference is enabled by the
- * feature flag.
- * @private
- */
- lockScreenMediaKeysPreferenceEnabled_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('lockScreenMediaKeysEnabled');
- },
- readOnly: true,
- },
-
/** @private */
showPasswordPromptDialog_: Boolean,
diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.html b/chromium/chrome/browser/resources/settings/people_page/people_page.html
index f2a605bb946..d6891e8da93 100644
--- a/chromium/chrome/browser/resources/settings/people_page/people_page.html
+++ b/chromium/chrome/browser/resources/settings/people_page/people_page.html
@@ -28,6 +28,7 @@
<if expr="chromeos">
<link rel="import" href="account_manager.html">
+<link rel="import" href="account_manager_browser_proxy.html">
<link rel="import" href="change_picture.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_picture/cr_png_behavior.html">
<link rel="import" href="fingerprint_list.html">
@@ -52,6 +53,11 @@
margin-inline-start: 20px;
}
+ .sync-row {
+ align-items: center;
+ flex: auto;
+ }
+
#profile-icon {
background: center / cover no-repeat;
border-radius: 20px;
@@ -60,29 +66,29 @@
width: 40px;
}
- iron-icon[icon='cr:sync'] {
- --iron-icon-fill-color: var(--google-green-refresh-700);
+ #sync-status.no-error {
+ --cr-link-row-start-icon-color: var(--google-green-refresh-700);
}
@media (prefers-color-scheme: dark) {
- iron-icon[icon='cr:sync'] {
- --iron-icon-fill-color: var(--google-green-refresh-300);
+ #sync-status.no-error {
+ --cr-link-row-start-icon-color: var(--google-green-refresh-300);
}
}
- #sync-status[actionable] iron-icon[icon='settings:sync-problem'] {
- --iron-icon-fill-color: var(--settings-error-color);
+ #sync-setup {
+ --cr-secondary-text: {
+ color: var(--settings-error-color);
+ }
}
- #sync-status[actionable].auth-error
- iron-icon[icon='settings:sync-disabled'] {
- --iron-icon-fill-color: var(--google-blue-500);
+ #sync-status[actionable].auth-error {
+ --cr-link-row-start-icon-color: var(--google-blue-500);
}
@media (prefers-color-scheme: dark) {
- #sync-status[actionable].auth-error
- iron-icon[icon='settings:sync-disabled'] {
- --iron-icon-fill-color: var(--google-blue-refresh-300);
+ #sync-status[actionable].auth-error {
+ --cr-link-row-start-icon-color: var(--google-blue-refresh-300);
}
}
@@ -95,8 +101,11 @@
border-top: var(--cr-separator-line);
}
- .settings-box[actionable].sync-error #syncSecondary {
- color: var(--settings-error-color);
+ #sync-status[actionable].sync-error {
+ --cr-link-row-start-icon-color: var(--settings-error-color);
+ --cr-secondary-text: {
+ color: var(--settings-error-color);
+ }
}
.icon-container {
@@ -151,12 +160,15 @@
</if>
<div id="picture-subpage-trigger" class="settings-box first two-line">
<template is="dom-if" if="[[syncStatus]]">
- <div id="profile-icon" on-click="onProfileTap_" actionable
+ <div id="profile-icon" on-click="onProfileTap_"
+ actionable$="[[isProfileActionable_]]"
style="background-image: [[getIconImageSet_(
profileIconUrl_)]]">
</div>
- <div class="middle two-line no-min-width" on-click="onProfileTap_"
- actionable>
+ <div class="middle two-line no-min-width"
+ id="profile-row"
+ on-click="onProfileTap_"
+ actionable$="[[isProfileActionable_]]">
<div class="flex text-elide settings-box-text">
<span id="profile-name">[[profileName_]]</span>
<div class="secondary" hidden="[[!syncStatus.signedIn]]">
@@ -169,8 +181,10 @@
aria-describedby="profile-name"></cr-icon-button>
</if>
<if expr="chromeos">
- <cr-icon-button class="subpage-arrow"
- aria-label="$i18n{changePictureTitle}"
+ <cr-icon-button class$="[[profileRowIconClass_]]"
+ id="profile-subpage-arrow"
+ hidden="[[!isProfileActionable_]]"
+ aria-label$="[[profileRowIconAriaLabel_]]"
aria-describedby="profile-name"></cr-icon-button>
</if>
</div>
@@ -217,29 +231,21 @@
<template is="dom-if"
if="[[isPreUnifiedConsentAdvancedSyncSettingsVisible_(
syncStatus, unifiedConsentEnabled_)]]">
- <div class$="settings-box two-line
- [[getSyncStatusClass_(syncStatus)]]"
- on-click="onSyncTap_" id="sync-status"
+ <cr-link-row id="sync-status"
+ class$="[[getSyncStatusClass_(syncStatus)]]"
+ label="$i18n{syncAndNonPersonalizedServices}"
+ sub-label="[[getSyncAndGoogleServicesSubtext_(syncStatus)]]"
+ on-click="onSyncTap_" start-icon="[[getSyncIcon_(syncStatus)]]"
actionable$="[[isSyncStatusActionable_(syncStatus)]]">
- <div class="icon-container">
- <iron-icon id="sync-icon" icon$="[[getSyncIcon_(syncStatus)]]">
- </iron-icon>
- </div>
- <div class="middle settings-box-text">
- $i18n{sync}
- <div class="secondary" id="syncSecondary">
- [[syncStatus.statusText]]
- </div>
- </div>
- <cr-icon-button class="subpage-arrow" aria-label="$i18n{sync}"
- aria-describedby="syncSecondary"></cr-icon-button>
- </div>
+ </cr-link-row>
</template>
<template is="dom-if" if="[[unifiedConsentEnabled_]]">
<cr-link-row id="sync-setup"
label="$i18n{syncAndNonPersonalizedServices}"
- on-click="onSyncTap_"></cr-link-row>
+ sub-label="[[getSyncAndGoogleServicesSubtext_(syncStatus)]]"
+ on-click="onSyncTap_">
+ </cr-link-row>
</template>
<if expr="not chromeos">
@@ -268,8 +274,7 @@
prefs.settings.enable_screen_lock.value)]]"
hidden="[[!pageVisibility.people.lockScreen]]"></cr-link-row>
- <template is="dom-if" if="[[shouldShowAccountManager_(
- isAccountManagerEnabled_, pageVisibility.people.googleAccounts)]]">
+ <template is="dom-if" if="[[pageVisibility.people.googleAccounts]]">
<cr-link-row id="account-manager-subpage-trigger" class="hr"
on-click="onAccountManagerTap_"
label="$i18n{accountManagerSubMenuLabel}"></cr-link-row>
@@ -283,8 +288,7 @@
hidden="[[!pageVisibility.people.manageUsers]]">
</cr-link-row>
- <template is="dom-if" if="[[shouldShowKerberos_(
- isKerberosEnabled_, pageVisibility.people.kerberosAccounts)]]">
+ <template is="dom-if" if="[[pageVisibility.people.kerberosAccounts]]">
<cr-link-row id="kerberos-accounts-subpage-trigger" class="hr"
on-click="onKerberosAccountsTap_"
label="$i18n{kerberosAccountsSubMenuLabel}">
@@ -371,8 +375,7 @@
<settings-change-picture></settings-change-picture>
</settings-subpage>
</template>
- <template is="dom-if" if="[[shouldShowAccountManager_(
- isAccountManagerEnabled_, pageVisibility.people.googleAccounts)]]">
+ <template is="dom-if" if="[[pageVisibility.people.googleAccounts]]">
<template is="dom-if" route-path="/accountManager">
<settings-subpage
associated-control="[[$$('#account-manager-subpage-trigger')]]"
@@ -381,8 +384,7 @@
</settings-subpage>
</template>
</template>
- <template is="dom-if" if="[[shouldShowKerberos_(
- isKerberosEnabled_, pageVisibility.people.kerberosAccounts)]]">
+ <template is="dom-if" if="[[pageVisibility.people.kerberosAccounts]]">
<template is="dom-if" route-path="/kerberosAccounts">
<settings-subpage
associated-control="[[$$('#kerberos-accounts-subpage-trigger')]]"
diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.js b/chromium/chrome/browser/resources/settings/people_page/people_page.js
index cce39871d20..ec7591d62f6 100644
--- a/chromium/chrome/browser/resources/settings/people_page/people_page.js
+++ b/chromium/chrome/browser/resources/settings/people_page/people_page.js
@@ -91,11 +91,67 @@ Polymer({
profileIconUrl_: String,
/**
+ * Whether the profile row is clickable. The behavior depends on the
+ * platform.
+ * @private
+ */
+ isProfileActionable_: {
+ type: Boolean,
+ value: function() {
+ if (!cr.isChromeOS) {
+ // Opens profile manager.
+ return true;
+ }
+ if (loadTimeData.getBoolean('showOSSettings')) {
+ // Pre-SplitSettings opens change picture.
+ return true;
+ }
+ // Post-SplitSettings links out to account manager if it is available.
+ return loadTimeData.getBoolean('isAccountManagerEnabled');
+ },
+ readOnly: true,
+ },
+
+ /**
* The current profile name.
* @private
*/
profileName_: String,
+ // <if expr="chromeos">
+ /** @private {string} */
+ profileRowIconClass_: {
+ type: String,
+ value: function() {
+ if (loadTimeData.getBoolean('showOSSettings')) {
+ // Pre-SplitSettings links internally to the change picture subpage.
+ return 'subpage-arrow';
+ } else {
+ // Post-SplitSettings links externally to account manager. If account
+ // manager isn't available the icon will be hidden.
+ return 'icon-external';
+ }
+ },
+ readOnly: true,
+ },
+
+ /** @private {string} */
+ profileRowIconAriaLabel_: {
+ type: String,
+ value: function() {
+ if (loadTimeData.getBoolean('showOSSettings')) {
+ // Pre-SplitSettings.
+ return this.i18n('changePictureTitle');
+ } else {
+ // Post-SplitSettings. If account manager isn't available the icon
+ // will be hidden so the label doesn't matter.
+ return this.i18n('accountManagerSubMenuLabel');
+ }
+ },
+ readOnly: true,
+ },
+ // </if>
+
// <if expr="not chromeos">
/** @private {boolean} */
shouldShowGoogleAccount_: {
@@ -128,30 +184,6 @@ Polymer({
readOnly: true,
},
- /**
- * True if Chrome OS Account Manager is enabled.
- * @private
- */
- isAccountManagerEnabled_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('isAccountManagerEnabled');
- },
- readOnly: true,
- },
-
- /**
- * True if Chrome OS Kerberos support is enabled.
- * @private
- */
- isKerberosEnabled_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('isKerberosEnabled');
- },
- readOnly: true,
- },
-
/** @private */
showParentalControls_: {
type: Boolean,
@@ -219,10 +251,24 @@ Polymer({
/** @override */
attached: function() {
- const profileInfoProxy = settings.ProfileInfoBrowserProxyImpl.getInstance();
- profileInfoProxy.getProfileInfo().then(this.handleProfileInfo_.bind(this));
- this.addWebUIListener(
- 'profile-info-changed', this.handleProfileInfo_.bind(this));
+ let useProfileNameAndIcon = true;
+ // <if expr="chromeos">
+ if (!loadTimeData.getBoolean('showOSSettings') &&
+ loadTimeData.getBoolean('isAccountManagerEnabled')) {
+ // If this is SplitSettings and we have the Google Account manager,
+ // prefer the GAIA name and icon.
+ useProfileNameAndIcon = false;
+ this.addWebUIListener(
+ 'accounts-changed', this.updateAccounts_.bind(this));
+ this.updateAccounts_();
+ }
+ // </if>
+ if (useProfileNameAndIcon) {
+ settings.ProfileInfoBrowserProxyImpl.getInstance().getProfileInfo().then(
+ this.handleProfileInfo_.bind(this));
+ this.addWebUIListener(
+ 'profile-info-changed', this.handleProfileInfo_.bind(this));
+ }
this.syncBrowserProxy_ = settings.SyncBrowserProxyImpl.getInstance();
this.syncBrowserProxy_.getSyncStatus().then(
@@ -283,6 +329,18 @@ Polymer({
// </if>
/**
+ * @return {string}
+ * @private
+ */
+ getSyncAndGoogleServicesSubtext_: function() {
+ if (this.syncStatus && this.syncStatus.hasError &&
+ this.syncStatus.statusText) {
+ return this.syncStatus.statusText;
+ }
+ return '';
+ },
+
+ /**
* Handler for when the profile's icon and name is updated.
* @private
* @param {!settings.ProfileInfo} info
@@ -304,6 +362,27 @@ Polymer({
this.profileIconUrl_ = info.iconUrl;
},
+ // <if expr="chromeos">
+ /**
+ * @private
+ * @suppress {checkTypes} The types only exists in Chrome OS builds, but
+ * Closure doesn't understand the <if> above.
+ */
+ updateAccounts_: async function() {
+ const /** @type {!Array<{settings.Account}>} */ accounts =
+ await settings.AccountManagerBrowserProxyImpl.getInstance()
+ .getAccounts();
+ // The user might not have any GAIA accounts (e.g. guest mode, Kerberos,
+ // Active Directory). In these cases the profile row is hidden, so there's
+ // nothing to do.
+ if (accounts.length == 0) {
+ return;
+ }
+ this.profileName_ = accounts[0].fullName;
+ this.profileIconUrl_ = accounts[0].pic;
+ },
+ // </if>
+
/**
* Handler for when the sync state is pushed from the browser.
* @param {?settings.SyncStatus} syncStatus
@@ -342,7 +421,14 @@ Polymer({
/** @private */
onProfileTap_: function() {
// <if expr="chromeos">
- settings.navigateTo(settings.routes.CHANGE_PICTURE);
+ if (loadTimeData.getBoolean('showOSSettings')) {
+ // Pre-SplitSettings.
+ settings.navigateTo(settings.routes.CHANGE_PICTURE);
+ } else if (loadTimeData.getBoolean('isAccountManagerEnabled')) {
+ // Post-SplitSettings. The browser C++ code loads OS settings in a window.
+ // Don't use window.open() because that creates an extra empty tab.
+ window.location.href = 'chrome://os-settings/accountManager';
+ }
// </if>
// <if expr="not chromeos">
settings.navigateTo(settings.routes.MANAGE_PROFILE);
@@ -459,18 +545,6 @@ Polymer({
onManageOtherPeople_: function() {
settings.navigateTo(settings.routes.ACCOUNTS);
},
-
- /** @private */
- shouldShowAccountManager_: function() {
- return this.isAccountManagerEnabled_ &&
- this.pageVisibility.people.googleAccounts;
- },
-
- /** @private */
- shouldShowKerberos_: function() {
- return this.isKerberosEnabled_ &&
- this.pageVisibility.people.kerberosAccounts;
- },
// </if>
// <if expr="not chromeos">
@@ -590,7 +664,7 @@ Polymer({
'sync-error';
}
- return '';
+ return 'no-error';
},
/**
diff --git a/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html b/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
index 6636a96d3eb..298e790f814 100644
--- a/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
+++ b/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
@@ -1,6 +1,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/chromeos/fingerprint/cr_fingerprint_progress_arc.html">
+<link rel="import" href="chrome://resources/cr_elements/chromeos/cr_lottie/cr_lottie.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
@@ -21,11 +22,6 @@
width: 500px;
}
- .fingerprint-scanner-tablet-power-button {
- background:
- url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_POWER_BUTTON_ANIMATION);
- }
-
.fingerprint-scanner-laptop-bottom-right {
background:
url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_BOTTOM_RIGHT_ANIMATION);
@@ -43,6 +39,11 @@
height: 240px;
}
+ #scannerLocationLottie {
+ height: 220px;
+ padding: 10px 0;
+ }
+
#messageDiv {
height: 20px;
}
@@ -67,11 +68,21 @@
aria-live="polite">
<span>[[getInstructionMessage_(step_, problemMessage_)]]</span>
</div>
- <div id="scannerLocation" hidden="[[!showScannerLocation_(step_)]]"
- class$="[[fingerprintScannerAnimationClass_]]"
- aria-label="$i18n{configureFingerprintScannerStepAriaLabel}"
- aria-live="polite" >
- </div>
+ <template is="dom-if" if="[[shouldUseLottieAnimation_]]">
+ <div id="scannerLocationLottie"
+ hidden="[[!showScannerLocation_(step_)]]" aria-live="polite"
+ aria-label="$i18n{configureFingerprintScannerStepAriaLabel}">
+ <cr-lottie animation-url="finger_print.json" autoplay>
+ </cr-lottie>
+ </div>
+ </template>
+ <template is="dom-if" if="[[!shouldUseLottieAnimation_]]">
+ <div id="scannerLocation" hidden="[[!showScannerLocation_(step_)]]"
+ class$="[[fingerprintScannerAnimationClass_]]"
+ aria-label="$i18n{configureFingerprintScannerStepAriaLabel}"
+ aria-live="polite" >
+ </div>
+ </template>
<cr-fingerprint-progress-arc id="arc" circle-radius="100"
hidden="[[!showArc_(step_)]]">
</cr-fingerprint-progress-arc>
diff --git a/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js b/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js
index 57168253b54..d0d6d0ec42b 100644
--- a/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js
+++ b/chromium/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js
@@ -101,7 +101,7 @@ Polymer({
loadTimeData.getInteger('fingerprintReaderLocation');
switch (fingerprintLocation) {
case settings.FingerprintLocation.TABLET_POWER_BUTTON:
- return 'fingerprint-scanner-tablet-power-button';
+ return '';
case settings.FingerprintLocation.KEYBOARD_TOP_RIGHT:
return 'fingerprint-scanner-laptop-top-right';
case settings.FingerprintLocation.KEYBOARD_BOTTOM_RIGHT:
@@ -111,6 +111,28 @@ Polymer({
},
readOnly: true,
},
+
+ /**
+ * True lottie animation file should be used instead of a png animation
+ * image sequence.
+ * @private {boolean}
+ */
+ shouldUseLottieAnimation_: {
+ type: Boolean,
+ value: function() {
+ if (!loadTimeData.getBoolean('fingerprintUnlockEnabled')) {
+ return false;
+ }
+
+ const fingerprintLocation =
+ loadTimeData.getInteger('fingerprintReaderLocation');
+ const isTabletPowerButton =
+ settings.FingerprintLocation.TABLET_POWER_BUTTON ==
+ fingerprintLocation;
+ return isTabletPowerButton;
+ },
+ readOnly: true,
+ }
},
/**
@@ -344,6 +366,5 @@ Polymer({
this.$.arc.setProgress(oldValue, newValue, newValue === 100);
},
-
});
})();
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
index 1b17c57b2ec..340398c2a47 100644
--- a/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -96,6 +96,9 @@ settings.StatusAction = {
* typedUrlsEnforced: boolean,
* typedUrlsRegistered: boolean,
* typedUrlsSynced: boolean,
+ * wifiConfigurationsEnforced: boolean,
+ * wifiConfigurationsRegistered: boolean,
+ * wifiConfigurationsSynced: boolean,
* }}
*/
settings.SyncPrefs;
@@ -211,6 +214,13 @@ cr.define('settings', function() {
* Opens the Google Activity Controls url in a new tab.
*/
openActivityControlsUrl() {}
+
+ /**
+ * Function to dispatch event sync-prefs-changed even without a change.
+ * This is used to decide whether we should show the link to password
+ * manager in passwords section on page load.
+ */
+ sendSyncPrefsChanged() {}
}
/**
@@ -298,6 +308,11 @@ cr.define('settings', function() {
chrome.metricsPrivate.recordUserAction(
'Signin_AccountSettings_GoogleActivityControlsClicked');
}
+
+ /** @override */
+ sendSyncPrefsChanged() {
+ chrome.send('SyncPrefsDispatch');
+ }
}
cr.addSingletonGetter(SyncBrowserProxyImpl);
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_controls.html b/chromium/chrome/browser/resources/settings/people_page/sync_controls.html
index 29466647fec..85151dcf0e4 100644
--- a/chromium/chrome/browser/resources/settings/people_page/sync_controls.html
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_controls.html
@@ -135,6 +135,22 @@
</cr-toggle>
</div>
+<if expr="chromeos">
+ <div class="list-item"
+ hidden="[[!syncPrefs.wifiConfigurationsRegistered]]">
+ <div id="wifiConfigurationsCheckboxLabel">
+ $i18n{wifiConfigurationsCheckboxLabel}
+ </div>
+ <cr-toggle checked="{{syncPrefs.wifiConfigurationsSynced}}"
+ on-change="onSingleSyncDataTypeChanged_"
+ disabled="[[shouldSyncCheckboxBeDisabled_(
+ syncPrefs.syncAllDataTypes,
+ syncPrefs.wifiConfigurationsEnforced)]]"
+ aria-labelledby="wifiConfigurationsCheckboxLabel">
+ </cr-toggle>
+ </div>
+</if>
+
<div class="list-item" hidden="[[!syncPrefs.autofillRegistered]]">
<div id="autofillCheckboxLabel">
$i18n{autofillCheckboxLabel}
diff --git a/chromium/chrome/browser/resources/settings/people_page/users_page.html b/chromium/chrome/browser/resources/settings/people_page/users_page.html
index 47c03a09a34..3b94c83970a 100644
--- a/chromium/chrome/browser/resources/settings/people_page/users_page.html
+++ b/chromium/chrome/browser/resources/settings/people_page/users_page.html
@@ -55,19 +55,19 @@
disabled="[[isEditingDisabled_(isOwner_, isWhitelistManaged_)]]"
inverted>
</settings-toggle-button>
- <div class="list-frame">
- <settings-user-list prefs="[[prefs]]"
- disabled="[[isEditingUsersDisabled_(isOwner_, isWhitelistManaged_,
- prefs.cros.accounts.allowGuest.value)]]">
- </settings-user-list>
- <div id="add-user-button" class="list-item"
- hidden="[[isEditingUsersDisabled_(isOwner_, isWhitelistManaged_,
- prefs.cros.accounts.allowGuest.value)]]">
- <a is="action-link" class="list-button" on-click="openAddUserDialog_">
- $i18n{addUsers}
- </a>
+ <template is="dom-if"
+ if="[[isEditingUsersEnabled_(isOwner_, isWhitelistManaged_,
+ prefs.cros.accounts.allowGuest.value, isChild_)]]">
+ <div class="list-frame" >
+ <settings-user-list prefs="[[prefs]]">
+ </settings-user-list>
+ <div id="add-user-button" class="list-item">
+ <a is="action-link" class="list-button" on-click="openAddUserDialog_">
+ $i18n{addUsers}
+ </a>
+ </div>
</div>
- </div>
+ </template>
<settings-users-add-user-dialog id="addUserDialog"
on-close="onAddUserDialogClose_">
</settings-users-add-user-dialog>
diff --git a/chromium/chrome/browser/resources/settings/people_page/users_page.js b/chromium/chrome/browser/resources/settings/people_page/users_page.js
index f8f19f31ff6..4a3ff206056 100644
--- a/chromium/chrome/browser/resources/settings/people_page/users_page.js
+++ b/chromium/chrome/browser/resources/settings/people_page/users_page.js
@@ -30,6 +30,14 @@ Polymer({
type: Boolean,
value: false,
},
+
+ /** @private */
+ isChild_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('isSupervised');
+ },
+ },
},
/** @override */
@@ -71,11 +79,13 @@ Polymer({
* @param {boolean} isOwner
* @param {boolean} isWhitelistManaged
* @param {boolean} allowGuest
+ * @param {boolean} isChild
* @private
* @return {boolean}
*/
- isEditingUsersDisabled_: function(isOwner, isWhitelistManaged, allowGuest) {
- return !isOwner || isWhitelistManaged || allowGuest;
+ isEditingUsersEnabled_: function(
+ isOwner, isWhitelistManaged, allowGuest, isChild) {
+ return isOwner && !isWhitelistManaged && !allowGuest && !isChild;
},
/** @return {boolean} */
diff --git a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
index 0f0acd7af8e..e7619959244 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
@@ -103,6 +103,7 @@ if (is_chromeos) {
":cups_nearby_printers",
":cups_printers_browser_proxy",
":cups_saved_printers",
+ "..:route",
"//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior",
"//ui/webui/resources/cr_elements/cr_toast:cr_toast",
diff --git a/chromium/chrome/browser/resources/settings/printing_page/OWNERS b/chromium/chrome/browser/resources/settings/printing_page/OWNERS
new file mode 100644
index 00000000000..1100e9746d7
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/printing_page/OWNERS
@@ -0,0 +1,2 @@
+khorimoto@chromium.org
+stevenjb@chromium.org
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
index 55b32a67b00..7c9a314bf87 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html
@@ -139,7 +139,8 @@
</cr-button>
<cr-button id="addPrinterButton" class="action-button"
on-click="addPressed_"
- disabled="[[!canAddPrinter_(newPrinter.*, inProgress_)]]">
+ disabled="[[!canAddPrinter_(newPrinter.*,
+ addPrinterInProgress_)]]">
$i18n{addPrinterButtonText}
</cr-button>
</div>
@@ -216,7 +217,8 @@
<cr-button class="action-button" id="addPrinterButton"
disabled="[[!canAddPrinter_(activePrinter.ppdManufacturer,
activePrinter.ppdModel,
- activePrinter.printerPPDPath)]]"
+ activePrinter.printerPPDPath,
+ addPrinterInProgress_)]]"
on-click="addPrinter_">
$i18n{addPrinterButtonText}
</cr-button>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
index c63057baedb..74f6940dfbb 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.js
@@ -387,6 +387,12 @@ Polymer({
value: '',
},
+ /** @private */
+ addPrinterInProgress_: {
+ type: Boolean,
+ value: false,
+ },
+
/**
* The error text to be displayed on the dialog.
* @private
@@ -431,6 +437,7 @@ Polymer({
* @private
* */
onPrinterAddedFailed_: function(result) {
+ this.addPrinterInProgress_ = false;
this.errorText_ = settings.printing.getErrorText(
/** @type {PrinterSetupResult} */ (result));
},
@@ -548,6 +555,7 @@ Polymer({
/** @private */
addPrinter_: function() {
+ this.addPrinterInProgress_ = true;
settings.CupsPrintersBrowserProxyImpl.getInstance()
.addCupsPrinter(this.activePrinter)
.then(
@@ -563,8 +571,9 @@ Polymer({
* @private
*/
canAddPrinter_: function(ppdManufacturer, ppdModel, printerPPDPath) {
- return settings.printing.isPPDInfoValid(
- ppdManufacturer, ppdModel, printerPPDPath);
+ return !this.addPrinterInProgress_ &&
+ settings.printing.isPPDInfoValid(
+ ppdManufacturer, ppdModel, printerPPDPath);
},
});
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
index 793770fd6dc..ab4137cfd86 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
@@ -59,22 +59,26 @@
on-change="onProtocolChange_"
disabled="[[!protocolSelectEnabled(isOnline_,
networkProtocolActive_)]]">
- <option value="ipp" disabled="[[!networkProtocolActive_]]">
+ <option value="ipp">
$i18n{printerProtocolIpp}
</option>
- <option value="ipps" disabled="[[!networkProtocolActive_]]">
+ <option value="ipps">
$i18n{printerProtocolIpps}
</option>
- <option value="http" disabled="[[!networkProtocolActive_]]">
+ <option value="http"
+ disabled="[[isAutoconfPrinter_(pendingPrinter_.*)]]">
$i18n{printerProtocolHttp}
</option>
- <option value="https" disabled="[[!networkProtocolActive_]]">
+ <option value="https"
+ disabled="[[isAutoconfPrinter_(pendingPrinter_.*)]]">
$i18n{printerProtocolHttps}
</option>
- <option value="socket" disabled="[[!networkProtocolActive_]]">
+ <option value="socket"
+ disabled="[[isAutoconfPrinter_(pendingPrinter_.*)]]">
$i18n{printerProtocolAppSocket}
</option>
- <option value="lpd" disabled="[[!networkProtocolActive_]]">
+ <option value="lpd"
+ disabled="[[isAutoconfPrinter_(pendingPrinter_.*)]]">
$i18n{printerProtocolLpd}
</option>
<option value="usb" disabled="[[networkProtocolActive_]]">
@@ -101,42 +105,45 @@
value="[[getPrinterURI_(pendingPrinter_)]]">
</cr-input>
</div>
- <div class="settings-box two-line">
- <cr-searchable-drop-down items="[[manufacturerList]]"
- id="printerPPDManufacturer"
- label="$i18n{printerManufacturer}"
- value="{{pendingPrinter_.ppdManufacturer}}"
- readonly="[[!isOnline_]]">
- </cr-searchable-drop-down>
- </div>
- <div class="settings-box two-line">
- <cr-searchable-drop-down items="[[modelList]]"
- id="printerPPDModel"
- label="$i18n{printerModel}"
- value="{{pendingPrinter_.ppdModel}}"
- readonly="[[!isOnline_]]">
- </cr-searchable-drop-down>
- </div>
- <div id="ppdLabel" class="cr-form-field-label">
- <span>$i18n{selectDriver}</span>
- <a href="$i18n{printingCUPSPrintPpdLearnMoreUrl}" target="_blank">
- $i18n{learnMore}
- </a>
- </div>
- <div class="settings-box two-line">
- <cr-input class="browse-file-input" readonly tabindex="-1"
- value="[[userPPD_]]" aria-labelledby="ppdLabel"
- error-message="$i18n{selectDriverErrorMessage}"
- invalid="[[invalidPPD_]]">
- </cr-input>
- <cr-button class="browse-button" on-click="onBrowseFile_"
- disabled="[[!isOnline_]]">
- $i18n{selectDriverButtonText}
- </cr-button>
- </div>
- <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
- <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
- </div>
+ <template id="makeAndModelSection" is="dom-if"
+ if="[[!isAutoconfPrinter_(pendingPrinter_.*)]]">
+ <div class="settings-box two-line">
+ <cr-searchable-drop-down items="[[manufacturerList]]"
+ id="printerPPDManufacturer"
+ label="$i18n{printerManufacturer}"
+ value="{{pendingPrinter_.ppdManufacturer}}"
+ readonly="[[!isOnline_]]">
+ </cr-searchable-drop-down>
+ </div>
+ <div class="settings-box two-line">
+ <cr-searchable-drop-down items="[[modelList]]"
+ id="printerPPDModel"
+ label="$i18n{printerModel}"
+ value="{{pendingPrinter_.ppdModel}}"
+ readonly="[[!isOnline_]]">
+ </cr-searchable-drop-down>
+ </div>
+ <div id="ppdLabel" class="cr-form-field-label">
+ <span>$i18n{selectDriver}</span>
+ <a href="$i18n{printingCUPSPrintPpdLearnMoreUrl}" target="_blank">
+ $i18n{learnMore}
+ </a>
+ </div>
+ <div class="settings-box two-line">
+ <cr-input class="browse-file-input" readonly tabindex="-1"
+ value="[[userPPD_]]" aria-labelledby="ppdLabel"
+ error-message="$i18n{selectDriverErrorMessage}"
+ invalid="[[invalidPPD_]]">
+ </cr-input>
+ <cr-button class="browse-button" on-click="onBrowseFile_"
+ disabled="[[!isOnline_]]">
+ $i18n{selectDriverButtonText}
+ </cr-button>
+ </div>
+ <div class="eula" id="eulaUrl" hidden="[[!eulaUrl_]]">
+ <a href="[[eulaUrl_]]" target="_blank">$i18n{printerEulaNotice}</a>
+ </div>
+ </template>
</div>
<div slot="dialog-buttons">
<cr-button class="cancel-button" on-click="onCancelTap_">
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
index 2832048cf28..7f78d1dfb77 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
@@ -125,14 +125,13 @@ Polymer({
'onModelChanged_(pendingPrinter_.ppdModel)',
],
- /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy} */
- networkConfigProxy_: null,
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
+ networkConfig_: null,
/** @override */
created: function() {
- this.networkConfigProxy_ =
- network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
+ .getMojoServiceRemote();
},
/** @override */
@@ -291,12 +290,20 @@ Polymer({
},
/**
+ * @return {boolean} Whether the current printer was auto configured.
+ * @private
+ */
+ isAutoconfPrinter_: function() {
+ return this.pendingPrinter_.printerPpdReference.autoconf;
+ },
+
+ /**
* @return {boolean} Whether the Save button is enabled.
* @private
*/
canSavePrinter_: function() {
return this.printerInfoChanged_ &&
- (this.isPrinterValid() || !this.isOnline_);
+ (this.isPrinterConfigured_() || !this.isOnline_);
},
/**
@@ -397,17 +404,20 @@ Polymer({
},
/**
- * Returns true if the printer has valid name, address, and PPD.
+ * Returns true if the printer has valid name, address, and valid PPD or was
+ * auto-configured.
* @return {boolean}
+ * @private
*/
- isPrinterValid: function() {
+ isPrinterConfigured_: function() {
return settings.printing.isNameAndAddressValid(this.pendingPrinter_) &&
- settings.printing.isPPDInfoValid(
- this.pendingPrinter_.ppdManufacturer, this.pendingPrinter_.ppdModel,
- this.pendingPrinter_.printerPPDPath);
+ (this.isAutoconfPrinter_() ||
+ settings.printing.isPPDInfoValid(
+ this.pendingPrinter_.ppdManufacturer,
+ this.pendingPrinter_.ppdModel,
+ this.pendingPrinter_.printerPPDPath));
},
-
/**
* Helper function to copy over modified fields to activePrinter.
* @private
@@ -431,7 +441,7 @@ Polymer({
* @private
*/
refreshNetworks_: function() {
- this.networkConfigProxy_
+ this.networkConfig_
.getNetworkStateList({
filter: chromeos.networkConfig.mojom.FilterType.kActive,
networkType: chromeos.networkConfig.mojom.NetworkType.kAll,
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html
index 428055b1b0f..7d6bf1824d2 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html
@@ -8,10 +8,20 @@
<dom-module id="settings-cups-nearby-printers">
<template>
- <style include="settings-shared"></style>
+ <style include="settings-shared">
+ #noPrinterMessage {
+ margin-inline-start: 60px;
+ margin-top: 20px;
+ }
+ </style>
<settings-cups-printers-entry-list printers="[[nearbyPrinters_]]"
search-term="[[searchTerm]]">
</settings-cups-printers-entry-list>
+ <div class="secondary" id="noPrinterMessage"
+ hidden="[[!shouldShowNoNearbyPrinterMessage_(searchTerm,
+ nearbyPrinters_)]]">
+ $i18n{noPrinterNearbyMessage}
+ </div>
</template>
<script src="cups_nearby_printers.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js
index 76652d815cd..aa4912c4010 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js
@@ -93,8 +93,10 @@ Polymer({
settings.CupsPrintersBrowserProxyImpl.getInstance()
.addDiscoveredPrinter(item.printerInfo.printerId)
- .then(this.onAddNearbyPrintersSucceeded_.bind(this,
- item.printerInfo.printerName));
+ .then(
+ this.onAddNearbyPrintersSucceeded_.bind(this,
+ item.printerInfo.printerName),
+ this.onAddNearbyPrinterFailed_.bind(this));
},
/**
@@ -114,7 +116,7 @@ Polymer({
},
/**
- * Handler for addDiscoveredPrinter.
+ * Handler for addDiscoveredPrinter success.
* @param {string} printerName
* @param {!PrinterSetupResult} result
* @private
@@ -123,5 +125,25 @@ Polymer({
this.fire(
'show-cups-printer-toast',
{resultCode: result, printerName: printerName});
+ },
+
+ /**
+ * Handler for addDiscoveredPrinter failure.
+ * @param {*} printer
+ * @private
+ */
+ onAddNearbyPrinterFailed_: function(printer) {
+ this.fire(
+ 'show-cups-printer-toast',
+ {resultCode: PrinterSetupResult.PRINTER_UNREACHABLE,
+ printerName: printer.printerName});
+ },
+
+ /**
+ * @return {boolean} Returns true if noPrinterMessage should be visible.
+ * @private
+ */
+ shouldShowNoNearbyPrinterMessage_: function() {
+ return !this.searchTerm && !this.nearbyPrinters_.length;
}
}); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_types.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_types.js
index 1d8487bf254..d2367b61c3b 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_types.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_types.js
@@ -15,6 +15,8 @@ let PrinterListEntry;
* These values correspond to the different types of printers available. Refer
* to cups_printer_management.md for more information about the different
* categories of printers.
+ *
+ * The types are numbered in desired sorting order for display.
*/
const PrinterType = {
SAVED: 0,
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html
index 7f23152c39a..6777282b161 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -3,6 +3,7 @@
<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_listener_behavior.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
<link rel="import" href="chrome://resources/html/action_link.html">
@@ -10,20 +11,22 @@
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="cups_add_printer_dialog.html">
<link rel="import" href="cups_edit_printer_dialog.html">
<link rel="import" href="cups_printer_shared_css.html">
<link rel="import" href="cups_printers_list.html">
<link rel="import" href="cups_saved_printers.html">
<link rel="import" href="cups_nearby_printers.html">
+<link rel="import" href="../route.html">
<dom-module id="settings-cups-printers">
<template>
- <style include="cups-printer-shared action-link">
+ <style include="cups-printer-shared action-link iron-flex
+ iron-flex-alignment">
.custom-list-item {
- align-items: center;
border-bottom: var(--cr-separator-line);
- display: flex;
min-height: var(--settings-row-min-height);
}
@@ -42,6 +45,25 @@
flex: 1;
}
+ #addManualPrinterIcon {
+ --iron-icon-fill-color: rgb(138, 180, 248);
+ --cr-icon-button-margin-end: 0;
+ }
+
+ #cloudOffIcon {
+ --iron-icon-fill-color: rgb(95, 99, 104);
+ margin-top: 10px;
+ }
+
+ #connectionMessage {
+ padding-inline-start: 20px;
+ }
+
+ #noConnectivityContentContainer {
+ border-bottom: var(--cr-separator-line);
+ padding-inline-start: 20px;
+ }
+
#noSearchResultsMessage {
color: var(--md-loading-message-color);
font-size: 16px;
@@ -49,6 +71,16 @@
margin-top: 80px;
text-align: center;
}
+
+ #savedPrintersContainer {
+ border-bottom: var(--cr-separator-line);
+ }
+
+ :host(:not([can-add-printer])) #addPrinterSection,
+ :host(:not([can-add-printer])) #nearbyPrinters {
+ opacity: var(--cr-disabled-opacity);
+ pointer-events: none;
+ }
</style>
<template is="dom-if" if="[[!enableUpdatedUi_]]">
@@ -58,11 +90,11 @@
<a href="$i18n{printingCUPSPrintLearnMoreUrl}" target="_blank">
$i18n{learnMore}
</a>
- <div class="secondary" hidden="[[canAddPrinter_]]">
+ <div class="secondary" hidden="[[canAddPrinter]]">
$i18n{requireNetworkMessage}
</div>
</div>
- <template is="dom-if" if="[[!addPrinterButtonActive_(canAddPrinter_,
+ <template is="dom-if" if="[[!addPrinterButtonActive_(canAddPrinter,
prefs.native_printing.user_native_printers_allowed.value)]]">
<cr-policy-pref-indicator
pref="[[prefs.native_printing.user_native_printers_allowed]]"
@@ -71,7 +103,7 @@
</template>
<cr-button class="action-button" id="addPrinter"
on-click="onAddPrinterTap_"
- disabled="[[!addPrinterButtonActive_(canAddPrinter_,
+ disabled="[[!addPrinterButtonActive_(canAddPrinter,
prefs.native_printing.user_native_printers_allowed.value)]]">
$i18n{addCupsPrinter}
</cr-button>
@@ -80,32 +112,52 @@
active-printer="{{activePrinter}}"
search-term="[[searchTerm]]">
</settings-cups-printers-list>
+
+ <div id="noSearchResultsMessage"
+ hidden="[[!showNoSearchResultsMessage_(searchTerm)]]">
+ $i18n{noSearchResults}
+ </div>
</template>
<template is="dom-if" if="[[enableUpdatedUi_]]">
- <div class="settings-box first">
- <div class="start">
- <span>$i18n{savedPrintersTitle}</span>
+ <template is="dom-if" if="[[!canAddPrinter]]">
+ <div id="noConnectivityContentContainer"
+ class="layout horizontal padded">
+ <iron-icon id="cloudOffIcon" icon="settings20:cloud-off"></iron-icon>
+ <div id="connectionMessage" class="layout vertical">
+ <div>$i18n{noInternetConnection}</div>
+ <div class="secondary">$i18n{checkNetworkAndTryAgain}</div>
+ </div>
</div>
- </div>
+ </template>
+
+ <template is="dom-if"
+ if="[[doesAccountHaveSavedPrinters_(savedPrinters_)]]" restamp>
+ <div id="savedPrintersContainer">
+ <div class="settings-box first">
+ <div class="start">
+ <span>$i18n{savedPrintersTitle}</span>
+ </div>
+ </div>
- <settings-cups-saved-printers id="savedPrinters"
- active-printer="{{activePrinter}}"
- search-term="[[searchTerm]]">
- </settings-cups-saved-printers>
+ <settings-cups-saved-printers id="savedPrinters"
+ active-printer="{{activePrinter}}"
+ saved-printers="[[savedPrinters_]]"
+ search-term="[[searchTerm]]">
+ </settings-cups-saved-printers>
+ </div>
+ </template>
<div class="padded first" id="nearbyPrinters">
<div>$i18n{nearbyPrintersListTitle}</div>
<span class="secondary">
$i18n{nearbyPrintersListDescription}
</span>
- <a href="$i18n{printingCUPSPrintLearnMoreUrl}" target="_blank">
+ <a href="$i18n{printingCUPSPrintLearnMoreUrl}"
+ target="_blank">
$i18n{learnMore}
</a>
- <div class="secondary" hidden="[[canAddPrinter_]]">
- $i18n{requireNetworkMessage}
- </div>
- <template is="dom-if" if="[[!addPrinterButtonActive_(canAddPrinter_,
+ <template is="dom-if" if="[[!addPrinterButtonActive_(canAddPrinter,
prefs.native_printing.user_native_printers_allowed.value)]]">
<cr-policy-pref-indicator
pref="[[prefs.native_printing.user_native_printers_allowed]]"
@@ -115,20 +167,22 @@
</div>
<div id="addPrinterSection">
- <div class="custom-list-item">
+ <div class="layout horizontal center custom-list-item">
<div id="addPrinterText">$i18n{addCupsPrinter}</div>
- <cr-button class="action-button" id="addPrinter"
+ <cr-icon-button class="action-button" id="addManualPrinterIcon"
+ iron-icon="settings20:printer-add"
on-click="onAddPrinterTap_"
- disabled="[[!addPrinterButtonActive_(canAddPrinter_,
- prefs.native_printing.user_native_printers_allowed.value)]]">
- $i18n{addCupsPrinter}
- </cr-button>
+ disabled="[[!addPrinterButtonActive_(canAddPrinter,
+ prefs.native_printing.user_native_printers_allowed.value)]]"
+ title="$i18n{addCupsPrinter}">
+ </cr-icon-button>
</div>
</div>
-
- <settings-cups-nearby-printers search-term="[[searchTerm]]"
- active-printer="{{activePrinter}}">
- </settings-cups-nearby-printers>
+ <template is="dom-if" if="[[canAddPrinter]]" restamp>
+ <settings-cups-nearby-printers search-term="[[searchTerm]]"
+ active-printer="{{activePrinter}}">
+ </settings-cups-nearby-printers>
+ </template>
</template>
<settings-cups-add-printer-dialog id="addPrinterDialog"
@@ -143,11 +197,6 @@
</settings-cups-edit-printer-dialog>
</template>
- <div id="noSearchResultsMessage"
- hidden="[[!showNoSearchResultsMessage_(searchTerm)]]">
- $i18n{noSearchResults}
- </div>
-
<cr-toast id="errorToast" duration="3000">
<div class="error-message" id="addPrinterDoneMessage">
[[addPrinterResultText_]]
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js
index 7e41ed47507..21109350ab6 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js
@@ -14,6 +14,7 @@ Polymer({
behaviors: [
CrNetworkListenerBehavior,
+ settings.RouteObserverBehavior,
WebUIListenerBehavior,
],
@@ -36,8 +37,20 @@ Polymer({
type: String,
},
- /** @private */
- canAddPrinter_: Boolean,
+ /** This is also used as an attribute for css styling. */
+ canAddPrinter: {
+ type: Boolean,
+ reflectToAttribute: true,
+ },
+
+ /**
+ * @type {!Array<!PrinterListEntry>}
+ * @private
+ */
+ savedPrinters_: {
+ type: Array,
+ value: () => [],
+ },
/** @private */
showCupsEditPrinterDialog_: Boolean,
@@ -65,19 +78,19 @@ Polymer({
'openManufacturerModelDialogForSpecifiedPrinter_',
},
- /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigProxy} */
- networkConfigProxy_: null,
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
+ networkConfig_: null,
/** @override */
created: function() {
- this.networkConfigProxy_ =
+ this.networkConfig_ =
network_config.MojoInterfaceProviderImpl.getInstance()
- .getMojoServiceProxy();
+ .getMojoServiceRemote();
},
/** @override */
attached: function() {
- this.networkConfigProxy_
+ this.networkConfig_
.getNetworkStateList({
filter: chromeos.networkConfig.mojom.FilterType.kActive,
networkType: chromeos.networkConfig.mojom.NetworkType.kAll,
@@ -90,9 +103,6 @@ Polymer({
if (this.enableUpdatedUi_) {
return;
}
-
- this.addWebUIListener(
- 'on-printers-changed', this.printersChanged_.bind(this));
},
/** @override */
@@ -100,6 +110,21 @@ Polymer({
this.updateCupsPrintersList_();
},
+
+ /**
+ * settings.RouteObserverBehavior
+ * @param {!settings.Route} route
+ * @protected
+ */
+ currentRouteChanged: function(route) {
+ if (route != settings.routes.CUPS_PRINTERS) {
+ cr.removeWebUIListener('on-printers-changed');
+ return;
+ }
+ cr.addWebUIListener(
+ 'on-printers-changed', this.onPrintersChanged_.bind(this));
+ },
+
/**
* CrosNetworkConfigObserver impl
* @param {!Array<chromeos.networkConfig.mojom.NetworkStateProperties>}
@@ -107,8 +132,12 @@ Polymer({
* @private
*/
onActiveNetworksChanged: function(networks) {
- this.canAddPrinter_ = networks.some(function(network) {
- return OncMojo.connectionStateIsConnected(network.connectionState);
+ this.canAddPrinter = networks.some(function(network) {
+ // Note: Check for kOnline rather than using
+ // OncMojo.connectionStateIsConnected() since the latter could return true
+ // for networks without connectivity (e.g., captive portals).
+ return network.connectionState ==
+ chromeos.networkConfig.mojom.ConnectionStateType.kOnline;
});
},
@@ -123,25 +152,23 @@ Polymer({
const printerName = event.detail.printerName;
switch (event.detail.resultCode) {
case PrinterSetupResult.SUCCESS:
- if (this.enableUpdatedUi_) {
- this.$$('#savedPrinters').updateSavedPrintersList();
- } else {
- this.updateCupsPrintersList_();
- }
+ this.updateCupsPrintersList_();
this.addPrinterResultText_ =
loadTimeData.getStringF('printerAddedSuccessfulMessage',
printerName);
break;
case PrinterSetupResult.EDIT_SUCCESS:
- if (this.enableUpdatedUi_) {
- this.$$('#savedPrinters').updateSavedPrintersList();
- } else {
- this.updateCupsPrintersList_();
- }
+ this.updateCupsPrintersList_();
this.addPrinterResultText_ =
loadTimeData.getStringF('printerEditedSuccessfulMessage',
printerName);
break;
+ case PrinterSetupResult.PRINTER_UNREACHABLE:
+ if (this.enableUpdatedUi_) {
+ this.addPrinterResultText_ =
+ loadTimeData.getStringF('printerUnavailableMessage', printerName);
+ break;
+ }
default:
assertNotReached();
}
@@ -163,15 +190,22 @@ Polymer({
updateCupsPrintersList_: function() {
settings.CupsPrintersBrowserProxyImpl.getInstance()
.getCupsPrintersList()
- .then(this.printersChanged_.bind(this));
+ .then(this.onPrintersChanged_.bind(this));
},
/**
* @param {!CupsPrintersList} cupsPrintersList
* @private
*/
- printersChanged_: function(cupsPrintersList) {
- this.printers = cupsPrintersList.printerList;
+ onPrintersChanged_: function(cupsPrintersList) {
+ if (this.enableUpdatedUi_) {
+ this.savedPrinters_ = cupsPrintersList.printerList.map(
+ printer => /** @type {!PrinterListEntry} */({
+ printerInfo: printer,
+ printerType: PrinterType.SAVED}));
+ } else {
+ this.printers = cupsPrintersList.printerList;
+ }
},
/** @private */
@@ -181,7 +215,9 @@ Polymer({
/** @private */
onAddPrinterDialogClose_: function() {
- cr.ui.focusWithoutInk(assert(this.$$('#addPrinter')));
+ cr.ui.focusWithoutInk(assert(
+ this.enableUpdatedUi_ ? this.$$('#addManualPrinterIcon')
+ : this.$$('#addPrinter')));
},
/** @private */
@@ -220,5 +256,13 @@ Polymer({
addPrinterButtonActive_: function(
connectedToNetwork, userNativePrintersAllowed) {
return connectedToNetwork && userNativePrintersAllowed;
+ },
+
+ /**
+ * @return {boolean} Whether |savedPrinters_| is empty.
+ * @private
+ */
+ doesAccountHaveSavedPrinters_: function() {
+ return !!this.savedPrinters_.length;
}
});
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html
index 164a8c5e637..c8df839a0ee 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html
@@ -1,7 +1,6 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="cups_printer_types.html">
<link rel="import" href="cups_printers_browser_proxy.html">
<link rel="import" href="../settings_shared_css.html">
@@ -29,17 +28,16 @@
</template>
<template is="dom-if"
if="[[isDiscoveredPrinter_(printerEntry.printerType)]]">
- <cr-button class="action-button"
+ <cr-button id="setupPrinterButton"
on-click="onOpenManufacturerModelDialogTap_">
- $i18n{configurePrinter}
+ $i18n{setupPrinter}
</cr-button>
</template>
<template is="dom-if"
if="[[isAutomaticPrinter_(printerEntry.printerType)]]">
- <cr-icon-button class="icon-add-circle"
- on-click="onAddAutomaticPrinterTap_"
- title="$i18n{moreActions}">
- </cr-icon-button>
+ <cr-button id="savePrinterButton" on-click="onAddAutomaticPrinterTap_">
+ $i18n{savePrinter}
+ </cr-button>
</template>
</div>
</template>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html
index fdb85be62b1..bf9fbaf1f9f 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html
@@ -19,6 +19,12 @@
iron-list {
flex: 1 1 auto;
}
+
+ #no-search-results {
+ margin-top: 20px;
+ text-align: center;
+ }
+
</style>
<iron-list class="list-frame vertical-list" id="printerEntryList"
items="[[filteredPrinters_]]">
@@ -27,6 +33,10 @@
</settings-cups-printers-entry>
</template>
</iron-list>
+ <div id="no-search-results"
+ hidden="[[!showNoSearchResultsMessage_]]">
+ $i18n{noSearchResults}
+ </div>
</template>
<script src="cups_printers_entry_list.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js
index 6037c31aecc..3fe5f69bd12 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js
@@ -37,7 +37,20 @@ Polymer({
* Search term for filtering |printers|.
* @type {string}
*/
- searchTerm: String,
+ searchTerm: {
+ type: String,
+ value: '',
+ },
+
+ /**
+ * Whether to show the no search results message.
+ * @type {boolean}
+ * @private
+ */
+ showNoSearchResultsMessage_: {
+ type: Boolean,
+ value: false,
+ },
},
observers: [
@@ -59,13 +72,30 @@ Polymer({
item =>this.matchesSearchTerm_(item.printerInfo,this.searchTerm)) :
this.printers.slice();
- updatedPrinters.sort((first, second) => {
- return settings.printing.alphabeticalSort(
- first.printerInfo, second.printerInfo);
- });
+ updatedPrinters.sort(this.sortPrinters_);
this.updateList('filteredPrinters_', printer => printer.printerInfo,
updatedPrinters);
+
+ this.showNoSearchResultsMessage_ =
+ !!this.searchTerm && !this.filteredPrinters_.length;
+ },
+
+
+ /**
+ * @param {!PrinterListEntry} first
+ * @param {!PrinterListEntry} second
+ * @return {number}
+ * @private
+ */
+ sortPrinters_: function(first, second) {
+ if (first.printerType == second.printerType) {
+ return settings.printing.alphabeticalSort(
+ first.printerInfo, second.printerInfo);
+ }
+
+ // PrinterType sort order maintained in cups_printer_types.js
+ return first.printerType - second.printerType;
},
/**
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html
index b343992525d..1bb09c08fc0 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html
@@ -19,7 +19,7 @@
</cr-action-menu>
<style include="settings-shared"></style>
- <settings-cups-printers-entry-list printers="[[savedPrinters_]]"
+ <settings-cups-printers-entry-list printers="[[savedPrinters]]"
search-term="[[searchTerm]]">
</settings-cups-printers-entry-list>
</template>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js
index a44b197232f..85ef694f1ec 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js
@@ -14,17 +14,13 @@ Polymer({
],
properties: {
- /**
- * @type {!Array<!PrinterListEntry>}
- * @private
- */
- savedPrinters_: {
+ /** @type {!Array<!PrinterListEntry>} */
+ savedPrinters: {
type: Array,
- value: () => [],
},
/**
- * Search term for filtering |savedPrinters_|.
+ * Search term for filtering |savedPrinters|.
* @type {string}
*/
searchTerm: {
@@ -60,35 +56,6 @@ Polymer({
this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance();
},
- /** @override */
- ready: function() {
- this.addWebUIListener(
- 'on-printers-changed', this.printersChanged_.bind(this));
- this.updateSavedPrintersList();
- },
-
- /** Public function to update the printer list. */
- updateSavedPrintersList: function() {
- settings.CupsPrintersBrowserProxyImpl.getInstance()
- .getCupsPrintersList()
- .then(this.printersChanged_.bind(this));
- },
-
- /**
- * @param {!CupsPrintersList} cupsPrintersList
- * @private
- */
- printersChanged_: function(cupsPrintersList) {
- if (!cupsPrintersList) {
- return;
- }
-
- this.savedPrinters_ = cupsPrintersList.printerList.map(
- printer => /** @type {!PrinterListEntry} */({
- printerInfo: printer,
- printerType: PrinterType.SAVED}));
- },
-
/**
* @param {!CustomEvent<{target: !HTMLElement, item: !PrinterListEntry}>} e
* @private
@@ -96,10 +63,10 @@ Polymer({
onOpenActionMenu_: function(e) {
const item = /** @type {!PrinterListEntry} */(e.detail.item);
this.activePrinterListEntryIndex_ =
- this.savedPrinters_.findIndex(
+ this.savedPrinters.findIndex(
printer => printer.printerInfo == item.printerInfo);
this.activePrinter =
- this.get(['savedPrinters_', this.activePrinterListEntryIndex_])
+ this.get(['savedPrinters', this.activePrinterListEntryIndex_])
.printerInfo;
const target = /** @type {!HTMLElement} */ (e.detail.target);
@@ -115,7 +82,6 @@ Polymer({
/** @private */
onRemoveTap_: function() {
- this.splice('savedPrinters_', this.activePrinterListEntryIndex_, 1);
this.browserProxy_.removeCupsPrinter(
this.activePrinter.printerId, this.activePrinter.printerName);
this.activePrinter = null;
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn b/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn
index a77c34ad919..028266d95fb 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/privacy_page/BUILD.gn
@@ -9,6 +9,7 @@ js_type_check("closure_compile") {
":personalization_options",
":privacy_page",
":privacy_page_browser_proxy",
+ ":security_keys_bio_enroll_dialog",
":security_keys_credential_management_dialog",
":security_keys_reset_dialog",
":security_keys_set_pin_dialog",
@@ -76,6 +77,7 @@ js_library("security_keys_subpage") {
js_library("security_keys_set_pin_dialog") {
deps = [
":security_keys_browser_proxy",
+ "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
"//ui/webui/resources/js:i18n_behavior",
]
externs_list = [ "$externs_path/settings_private.js" ]
@@ -103,3 +105,13 @@ js_library("security_keys_reset_dialog") {
]
externs_list = [ "$externs_path/settings_private.js" ]
}
+
+js_library("security_keys_bio_enroll_dialog") {
+ deps = [
+ ":security_keys_browser_proxy",
+ ":security_keys_pin_field",
+ "//ui/webui/resources/cr_elements/cr_fingerprint:cr_fingerprint_progress_arc",
+ "//ui/webui/resources/js:i18n_behavior",
+ ]
+ externs_list = [ "$externs_path/settings_private.js" ]
+}
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 283cfb4c790..1ad29354d5c 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -396,23 +396,21 @@
</category-setting-exceptions>
</settings-subpage>
</template>
- <template is="dom-if" if="[[enableSensorsContentSetting_]]" no-search>
- <template is="dom-if" route-path="/content/sensors" no-search>
- <settings-subpage page-title="$i18n{siteSettingsSensors}"
- search-label="$i18n{siteSettingsAllSitesSearch}"
- search-term="{{searchFilter_}}">
- <category-default-setting
- toggle-off-label="$i18n{siteSettingsSensorsBlock}"
- toggle-on-label="$i18n{siteSettingsSensorsAllow}"
- category="{{ContentSettingsTypes.SENSORS}}">
- </category-default-setting>
- <category-setting-exceptions
- category="{{ContentSettingsTypes.SENSORS}}" read-only-list
- block-header="$i18n{siteSettingsBlock}"
- search-filter="[[searchFilter_]]">
- </category-setting-exceptions>
- </settings-subpage>
- </template>
+ <template is="dom-if" route-path="/content/sensors" no-search>
+ <settings-subpage page-title="$i18n{siteSettingsSensors}"
+ search-label="$i18n{siteSettingsAllSitesSearch}"
+ search-term="{{searchFilter_}}">
+ <category-default-setting
+ toggle-off-label="$i18n{siteSettingsSensorsBlock}"
+ toggle-on-label="$i18n{siteSettingsSensorsAllow}"
+ category="{{ContentSettingsTypes.SENSORS}}">
+ </category-default-setting>
+ <category-setting-exceptions
+ category="{{ContentSettingsTypes.SENSORS}}" read-only-list
+ block-header="$i18n{siteSettingsBlock}"
+ search-filter="[[searchFilter_]]">
+ </category-setting-exceptions>
+ </settings-subpage>
</template>
<template is="dom-if" route-path="/content/notifications" no-search>
<settings-subpage page-title="$i18n{siteSettingsCategoryNotifications}"
@@ -557,6 +555,25 @@
</settings-subpage>
</template>
</template>
+ <template is="dom-if" if="[[enableNativeFileSystemWriteContentSetting_]]">
+ <template is="dom-if" route-path="/content/filesystem" no-search>
+ <settings-subpage
+ page-title="$i18n{siteSettingsNativeFileSystemWrite}">
+ <category-default-setting
+ toggle-off-label="$i18n{siteSettingsNativeFileSystemWriteBlock}"
+ toggle-on-label=
+ "$i18n{siteSettingsNativeFileSystemWriteAskRecommended}"
+ category="{{ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE}}">
+ </category-default-setting>
+ <category-setting-exceptions
+ category="{{ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE}}"
+ read-only-list
+ block-header="$i18n{siteSettingsBlock}"
+ search-filter="[[searchFilter_]]">
+ </category-setting-exceptions>
+ </settings-subpage>
+ </template>
+ </template>
<template is="dom-if" route-path="/content/siteDetails" no-search>
<settings-subpage page-title="[[pageTitle]]">
<site-details
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
index 49ea7f9dae2..57b42d06dee 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -119,15 +119,6 @@ Polymer({
},
/** @private */
- enableSensorsContentSetting_: {
- type: Boolean,
- readOnly: true,
- value: function() {
- return loadTimeData.getBoolean('enableSensorsContentSetting');
- }
- },
-
- /** @private */
enableExperimentalWebPlatformFeatures_: {
type: Boolean,
value: function() {
@@ -152,6 +143,15 @@ Polymer({
}
},
+ /** @private */
+ enableNativeFileSystemWriteContentSetting_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean(
+ 'enableNativeFileSystemWriteContentSetting');
+ }
+ },
+
/** @private {!Map<string, string>} */
focusConfig_: {
type: Object,
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html
new file mode 100644
index 00000000000..7569eead29a
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html
@@ -0,0 +1,118 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.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">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
+<link rel="import" href="../i18n_setup.html">
+<link rel="import" href="../settings_shared_css.html">
+<link rel="import" href="../site_favicon.html">
+<link rel="import" href="security_keys_browser_proxy.html">
+<link rel="import" href="security_keys_pin_field.html">
+
+<dom-module id="settings-security-keys-bio-enroll-dialog">
+ <template>
+ <style include="settings-shared">
+ #header {
+ display: flex;
+ }
+
+ iron-icon {
+ padding-inline-end: 12px;
+ }
+
+ .name {
+ flex: 3;
+ }
+
+ #dialog::part(body-container) {
+ overflow-y: hidden;
+ }
+ </style>
+
+ <cr-dialog id="dialog" close-text="$i18n{cancel}" ignore-popstate
+ on-close="onDialogClosed_">
+ <div slot="title">$i18n{securityKeysBioEnrollmentDialogTitle}</div>
+
+ <div slot="body">
+ <iron-pages attr-for-selected="id" selected="[[dialogPage_]]"
+ on-iron-select="onIronSelect_">
+ <div id="initial">
+ <p>$i18n{securityKeysBioEnrollmentTouch}</p>
+ <paper-spinner-lite style="padding-bottom: 16px;" active>
+ </paper-spinner-lite>
+ </div>
+
+ <div id="pinPrompt">
+ <p>$i18n{securityKeysBioEnrollmentPinPrompt}</p>
+ <settings-security-keys-pin-field id="pin">
+ </settings-security-keys-pin-field>
+ </div>
+
+ <div id="enrollments">
+ <div class="settings-box first">
+ <p class="start" hidden="[[hasSome_(enrollments_)]]">
+ $i18n{securityKeysBioEnrollmentNoEnrollments}</p>
+ <p class="start" hidden="[[!hasSome_(enrollments_)]]">
+ $i18n{securityKeysBioEnrollmentLabel}</p>
+ <cr-button id="addButton" on-click="addButtonClick_"
+ hidden="[[!addButtonVisible_]]"
+ class="secondary-button header-aligned-button">
+ $i18n{add}
+ </cr-button>
+ </div>
+ <div id="container">
+ <iron-list id="enrollmentList" items="[[enrollments_]]"
+ class="cr-separators">
+ <template>
+ <div class="list-item">
+ <iron-icon icon="cr-fingerprint-icon:enrollment-done">
+ </iron-icon>
+ <div class="name" aria-label="[[item.name]]">
+ [[item.name]]
+ </div>
+ <cr-icon-button class="icon-clear"
+ aria-label="i18n{securityKeysBioEnrollmentDelete}"
+ on-click="deleteEnrollment_"
+ disabled="[[deleteInProgress_]]">
+ </cr-icon-button>
+ </div>
+ </template>
+ </iron-list>
+ </div>
+ </div>
+
+ <div id="enroll">
+ <p>$i18n{securityKeysBioEnrollmentEnrollingLabel}</p>
+ <cr-fingerprint-progress-arc id="arc"></cr-fingerprint-progress-arc>
+ </div>
+
+ <div id="error">[[errorMsg_]]</div>
+ </iron-pages>
+ </div>
+
+ <div slot="button-container">
+ <cr-button id="cancelButton" class="cancel-button"
+ on-click="cancel_" hidden="[[!cancelButtonVisible_]]">
+ $i18n{cancel}
+ </cr-button>
+ <cr-button id="okButton" class="action-button"
+ on-click="okButtonClick_" hidden="[[!okButtonVisible_]]">
+ $i18n{ok}
+ </cr-button>
+ <cr-button id="doneButton" class="action-button"
+ on-click="done_" hidden="[[!doneButtonVisible_]]">
+ $i18n{done}
+ </cr-button>
+ </div>
+ </cr-dialog>
+
+ </template>
+ <script src="security_keys_bio_enroll_dialog.js"></script>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js
new file mode 100644
index 00000000000..1f251c65aa4
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js
@@ -0,0 +1,273 @@
+// 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.
+
+(function() {
+'use strict';
+
+/**
+ * @fileoverview 'settings-security-keys-bio-enroll-dialog' is a dialog for
+ * listing, adding, renaming, and deleting biometric enrollments stored on a
+ * security key.
+ */
+Polymer({
+ is: 'settings-security-keys-bio-enroll-dialog',
+
+ behaviors: [
+ I18nBehavior,
+ WebUIListenerBehavior,
+ ],
+
+ properties: {
+ /** @private */
+ addButtonVisible_: Boolean,
+
+ /** @private */
+ cancelButtonVisible_: Boolean,
+
+ /** @private */
+ deleteInProgress_: Boolean,
+
+ /**
+ * The ID of the element currently shown in the dialog.
+ * @private
+ */
+ dialogPage_: {
+ type: String,
+ value: 'initial',
+ observer: 'dialogPageChanged_',
+ },
+
+ /** @private */
+ doneButtonVisible_: Boolean,
+
+ /**
+ * The list of enrollments displayed.
+ * @private {!Array<!Enrollment>}
+ */
+ enrollments_: Array,
+
+ /** @private */
+ okButtonVisible_: Boolean,
+ },
+
+ /** @private {?settings.SecurityKeysBioEnrollProxyImpl} */
+ browserProxy_: null,
+
+ /** @private */
+ maxSamples_: Number,
+
+ /** @override */
+ attached: function() {
+ this.$.dialog.showModal();
+ this.addWebUIListener(
+ 'security-keys-bio-enroll-error', this.onError_.bind(this));
+ this.addWebUIListener(
+ 'security-keys-bio-enroll-status', this.onEnrolling_.bind(this));
+ this.browserProxy_ = settings.SecurityKeysBioEnrollProxyImpl.getInstance();
+ this.browserProxy_.startBioEnroll().then(
+ this.collectPIN_.bind(this), () => {});
+ },
+
+ /** @private */
+ collectPIN_: function() {
+ this.dialogPage_ = 'pinPrompt';
+ this.$.pin.focus();
+ },
+
+ /**
+ * @private
+ * @param {string} error
+ */
+ onError_: function(error) {
+ this.errorMsg_ = error;
+ this.dialogPage_ = 'error';
+ },
+
+ /** @private */
+ submitPIN_: function() {
+ if (!this.$.pin.validate()) {
+ return;
+ }
+ this.browserProxy_.providePIN(this.$.pin.value).then((retries) => {
+ if (retries != null) {
+ this.$.pin.showIncorrectPINError(retries);
+ return;
+ }
+
+ this.browserProxy_.enumerateEnrollments().then(
+ this.onEnrollments_.bind(this));
+ }, () => {});
+ },
+
+ /**
+ * @private
+ * @param {!Array<!Enrollment>} enrollments
+ */
+ onEnrollments_: function(enrollments) {
+ this.enrollments_ = enrollments;
+ this.$.enrollmentList.fire('iron-resize');
+ this.dialogPage_ = 'enrollments';
+ },
+
+ /** @private */
+ dialogPageChanged_: function() {
+ switch (this.dialogPage_) {
+ case 'initial':
+ this.addButtonVisible_ = false;
+ this.cancelButtonVisible_ = true;
+ this.okButtonVisible_ = false;
+ this.doneButtonVisible_ = false;
+ break;
+ case 'pinPrompt':
+ this.addButtonVisible_ = false;
+ this.cancelButtonVisible_ = true;
+ this.okButtonVisible_ = true;
+ this.doneButtonVisible_ = false;
+ break;
+ case 'enrollments':
+ this.addButtonVisible_ = true;
+ this.cancelButtonVisible_ = false;
+ this.okButtonVisible_ = false;
+ this.doneButtonVisible_ = true;
+ break;
+ case 'enroll':
+ this.addButtonVisible_ = false;
+ this.cancelButtonVisible_ = true;
+ this.okButtonVisible_ = false;
+ this.doneButtonVisible_ = false;
+ break;
+ case 'error':
+ this.addButtonVisible_ = false;
+ this.cancelButtonVisible_ = false;
+ this.okButtonVisible_ = false;
+ this.doneButtonVisible_ = true;
+ break;
+ default:
+ assertNotReached();
+ }
+ this.fire('bio-enroll-dialog-ready-for-testing');
+ },
+
+ /** @private */
+ addButtonClick_: function() {
+ assert(this.dialogPage_ == 'enrollments');
+
+ this.maxSamples_ = -1; // Reset maxSamples_ before enrolling starts.
+ this.$.arc.reset();
+ this.cancelButtonVisible_ = true;
+ this.okButtonVisible_ = false;
+
+ this.dialogPage_ = 'enroll';
+ this.browserProxy_.startEnrolling().then(
+ this.onEnrolling_.bind(this), () => {});
+ },
+
+ /**
+ * @private
+ * @param {!EnrollmentStatus} response
+ */
+ onEnrolling_: function(response) {
+ if (this.maxSamples_ == -1 && response.status != null) {
+ if (response.status == 0) {
+ // If the first sample is valid, remaining is one less than max samples
+ // required.
+ this.maxSamples_ = response.remaining + 1;
+ } else {
+ // If the first sample failed for any reason (timed out, key full, etc),
+ // the remaining number of samples is the max samples required.
+ this.maxSamples_ = response.remaining;
+ }
+ }
+ // If 0 samples remain, the enrollment has finished in some state.
+ // Currently not checking response['code'] for an error.
+ this.$.arc.setProgress(
+ 100 - (100 * (response.remaining + 1) / this.maxSamples_),
+ 100 - (100 * response.remaining / this.maxSamples_),
+ response.remaining == 0);
+ if (response.remaining == 0) {
+ this.cancelButtonVisible_ = false;
+ this.okButtonVisible_ = true;
+ }
+ this.fire('bio-enroll-dialog-ready-for-testing');
+ },
+
+ /** @private */
+ okButtonClick_: function() {
+ switch (this.dialogPage_) {
+ case 'pinPrompt':
+ this.submitPIN_();
+ break;
+ case 'enroll':
+ this.browserProxy_.enumerateEnrollments().then(
+ this.onEnrollments_.bind(this), () => {});
+ break;
+ default:
+ assertNotReached();
+ }
+ },
+
+ /** @private */
+ cancel_: function() {
+ if (this.dialogPage_ == 'enroll') {
+ this.browserProxy_.cancelEnrollment().then(
+ this.cancelEnroll_.bind(this), () => {});
+ } else {
+ this.done_();
+ }
+ },
+
+ /** @private */
+ cancelEnroll_: function() {
+ // Cancelling from the enrolling screen redirects to the enrollments
+ // list, so request another enumeration to display.
+ this.browserProxy_.enumerateEnrollments().then(
+ this.onEnrollments_.bind(this), () => {});
+ },
+
+ /** @private */
+ done_: function() {
+ this.$.dialog.close();
+ },
+
+ /** @private */
+ onDialogClosed_: function() {
+ this.browserProxy_.close();
+ },
+
+ /**
+ * @private
+ * @param {!Event} e
+ */
+ onIronSelect_: function(e) {
+ // Prevent this event from bubbling since it is unnecessarily triggering the
+ // listener within settings-animated-pages.
+ e.stopPropagation();
+ },
+
+ /**
+ * @private
+ * @param {?Array} list
+ * @return {boolean} true if the list exists and has items.
+ */
+ hasSome_: function(list) {
+ return !!(list && list.length);
+ },
+
+ /**
+ * @private
+ * @param {!DomRepeatEvent} event
+ */
+ deleteEnrollment_: function(event) {
+ if (this.deleteInProgress_) {
+ return;
+ }
+ this.deleteInProgress_ = true;
+ const enrollment = this.enrollments_[event.model.index];
+ this.browserProxy_.deleteEnrollment(enrollment.id).then(enrollments => {
+ this.deleteInProgress_ = false;
+ this.onEnrollments_(enrollments);
+ });
+ }
+});
+})();
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js
index 0d6f5fb4ce3..00a55d9f52d 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js
@@ -26,6 +26,31 @@ cr.exportPath('settings');
*/
let Credential;
+/**
+ * EnrollmentStatus represents the current status of an enrollment suboperation,
+ * where 'remaining' indicates the number of samples left, 'status' indicates
+ * the last enrollment status, and 'code' indicates the CtapDeviceResponseCode.
+ * For each enrollment sample, 'status' is set - when the enrollment operation
+ * reaches an end state, 'code' is set. A 'code' of CtapDeviceResponseCode 0
+ * indicates successful enrollment.
+ *
+ * @typedef {{status: ?number,
+ * code: ?number,
+ * remaining: number}}
+ * @see chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+ */
+let EnrollmentStatus;
+
+/**
+ * Enrollment represents a valid fingerprint template stored on a security key,
+ * which can be used in a user verification request.
+ *
+ * @typedef {{name: string,
+ * id: string}}
+ * @see chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+ */
+let Enrollment;
+
cr.define('settings', function() {
/** @interface */
class SecurityKeysPINBrowserProxy {
@@ -118,6 +143,78 @@ cr.define('settings', function() {
close() {}
}
+ /** @interface */
+ class SecurityKeysBioEnrollProxy {
+ /**
+ * Starts a biometric enrollment operation.
+ *
+ * Callers must listen to errors that can occur during this operation via a
+ * 'security-keys-bio-enrollment-error' WebUIListener. Values received via
+ * this listener are localized error strings. The WebListener may fire at
+ * any point during the operation (enrolling, deleting, etc) and when it
+ * fires, the operation must be considered terminated.
+ *
+ * @return {!Promise} resolves when the handler is ready for the
+ * authentcation PIN to be provided.
+ */
+ startBioEnroll() {}
+
+ /**
+ * Provides a PIN for a biometric enrollment operation. The startBioEnroll()
+ * Promise must have resolved before this method may be called.
+ *
+ * @return {!Promise<?number>} resolves with null if the PIN was correct,
+ * the number of retries remaining otherwise.
+ */
+ providePIN(pin) {}
+
+ /**
+ * Enumerates enrollments on the authenticator. A correct PIN must have
+ * previously been supplied via bioEnrollProvidePIN() before this method may
+ * be called.
+ *
+ * @return {!Promise<!Array<!Enrollment>>}
+ */
+ enumerateEnrollments() {}
+
+ /**
+ * Move the operation into enrolling mode, which instructs the authenticator
+ * to start sampling for touches.
+ *
+ * Callers must listen to status updates that will occur during this
+ * suboperation via a 'security-keys-bio-enroll-status' WebListener. Values
+ * received via this listener are DictionaryValues with two elements (see
+ * below). When the WebListener fires, the authenticator has either timed
+ * out waiting for a touch, or has successfully processed a touch. Any
+ * errors will fire the 'security-keys-bio-enrollment-error' WebListener.
+ *
+ * @return {!Promise<!EnrollmentStatus>} resolves when the enrollment
+ * operation is finished successfully.
+ */
+ startEnrolling() {}
+
+ /**
+ * Cancel an ongoing enrollment suboperation. This can safely be called at
+ * any time and only has an impact when the authenticator is currently
+ * sampling.
+ *
+ * @return {!Promise} resolves when the ongoing enrollment suboperation has
+ * been cancelled.
+ */
+ cancelEnrollment() {}
+
+ /**
+ * Deletes the enrollment with the given ID.
+ *
+ * @param {string} id
+ * @return {!Promise<!Array<!Enrollment>>} The remaining enrollments.
+ */
+ deleteEnrollment(id) {}
+
+ /** Cancels all outstanding operations. */
+ close() {}
+ }
+
/** @implements {settings.SecurityKeysPINBrowserProxy} */
class SecurityKeysPINBrowserProxyImpl {
/** @override */
@@ -182,11 +279,50 @@ cr.define('settings', function() {
}
}
+ /** @implements {settings.SecurityKeysBioEnrollProxy} */
+ class SecurityKeysBioEnrollProxyImpl {
+ /** @override */
+ startBioEnroll() {
+ return cr.sendWithPromise('securityKeyBioEnrollStart');
+ }
+
+ /** @override */
+ providePIN(pin) {
+ return cr.sendWithPromise('securityKeyBioEnrollProvidePIN', pin);
+ }
+
+ /** @override */
+ enumerateEnrollments() {
+ return cr.sendWithPromise('securityKeyBioEnrollEnumerate');
+ }
+
+ /** @override */
+ startEnrolling() {
+ return cr.sendWithPromise('securityKeyBioEnrollStartEnrolling');
+ }
+
+ /** @override */
+ cancelEnrollment() {
+ return cr.sendWithPromise('securityKeyBioEnrollCancel');
+ }
+
+ /** @override */
+ deleteEnrollment(id) {
+ return cr.sendWithPromise('securityKeyBioEnrollDelete', id);
+ }
+
+ /** @override */
+ close() {
+ return chrome.send('securityKeyBioEnrollClose');
+ }
+ }
+
// The singleton instance_ is replaced with a test version of this wrapper
// during testing.
cr.addSingletonGetter(SecurityKeysPINBrowserProxyImpl);
cr.addSingletonGetter(SecurityKeysCredentialBrowserProxyImpl);
cr.addSingletonGetter(SecurityKeysResetBrowserProxyImpl);
+ cr.addSingletonGetter(SecurityKeysBioEnrollProxyImpl);
return {
SecurityKeysPINBrowserProxy: SecurityKeysPINBrowserProxy,
@@ -196,5 +332,7 @@ cr.define('settings', function() {
SecurityKeysCredentialBrowserProxyImpl,
SecurityKeysResetBrowserProxy: SecurityKeysResetBrowserProxy,
SecurityKeysResetBrowserProxyImpl: SecurityKeysResetBrowserProxyImpl,
+ SecurityKeysBioEnrollProxy: SecurityKeysBioEnrollProxy,
+ SecurityKeysBioEnrollProxyImpl: SecurityKeysBioEnrollProxyImpl,
};
});
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
index a67ac0a89bc..0045f54d6a2 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
@@ -1,5 +1,6 @@
<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
index ce300e509eb..146f22674b3 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
@@ -166,6 +166,8 @@ Polymer({
this.confirmButtonVisible_ = false;
this.closeButtonVisible_ = true;
break;
+ default:
+ assertNotReached();
}
this.fire('credential-management-dialog-ready-for-testing');
},
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html
index 2e6c0a4942f..94f201d1cf2 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.html
@@ -6,6 +6,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
<link rel="import" href="../i18n_setup.html">
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
index 4cadbca4e28..813d93e51d5 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
@@ -149,6 +149,10 @@ Polymer({
this.browserProxy_ = settings.SecurityKeysPINBrowserProxyImpl.getInstance();
this.$.dialog.showModal();
+ Polymer.RenderStatus.afterNextRender(this, function() {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ });
+
this.browserProxy_.startSetPIN().then(([success, errorCode]) => {
if (success) {
// Operation is complete. errorCode is a CTAP error code. See
@@ -335,6 +339,7 @@ Polymer({
this.currentPINError_ = this.isValidPIN_(this.currentPIN_);
if (this.currentPINError_ != '') {
this.focusOn_(this.$.currentPIN);
+ this.fire('iron-announce', {text: this.currentPINError_});
this.fire('ui-ready'); // for test synchronization.
return;
}
@@ -343,6 +348,7 @@ Polymer({
this.newPINError_ = this.isValidPIN_(this.newPIN_);
if (this.newPINError_ != '') {
this.focusOn_(this.$.newPIN);
+ this.fire('iron-announce', {text: this.newPINError_});
this.fire('ui-ready'); // for test synchronization.
return;
}
@@ -350,6 +356,7 @@ Polymer({
if (this.newPIN_ != this.confirmPIN_) {
this.confirmPINError_ = this.i18n('securityKeysPINMismatch');
this.focusOn_(this.$.confirmPIN);
+ this.fire('iron-announce', {text: this.confirmPINError_});
this.fire('ui-ready'); // for test synchronization.
return;
}
@@ -374,6 +381,7 @@ Polymer({
this.currentPINError_ = this.mismatchError_(this.retries_);
this.setPINButtonValid_ = true;
this.focusOn_(this.$.currentPIN);
+ this.fire('iron-announce', {text: this.currentPINError_});
this.fire('ui-ready'); // for test synchronization.
} else {
// Unknown error.
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.html
index e1d58b335fd..8f242c43a58 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.html
@@ -6,6 +6,7 @@
<link rel="import" href="../settings_shared_css.html">
<link rel="import" href="security_keys_credential_management_dialog.html">
+<link rel="import" href="security_keys_bio_enroll_dialog.html">
<link rel="import" href="security_keys_set_pin_dialog.html">
<link rel="import" href="security_keys_reset_dialog.html">
@@ -32,6 +33,14 @@
label="$i18n{securityKeysReset}"
sub-label="$i18n{securityKeysResetDesc}"
on-click="onReset_"></cr-link-row>
+ <template is="dom-if" if="[[enableBioEnrollment_]]">
+ <cr-link-row
+ id="bioEnrollButton"
+ class="hr"
+ label="$i18n{securityKeysBioEnrollmentDialogTitle}"
+ sub-label="$i18n{securityKeysBioEnrollmentSubpageDescription}"
+ on-click="onBioEnroll_"></cr-link-row>
+ </template>
<template is="dom-if" if="[[showSetPINDialog_]]" restamp>
<settings-security-keys-set-pin-dialog on-close="onSetPINDialogClosed_">
@@ -49,6 +58,12 @@
</settings-security-keys-reset-dialog>
</template>
+ <template is="dom-if" if="[[showBioEnrollDialog_]]" restamp>
+ <settings-security-keys-bio-enroll-dialog
+ on-close="onBioEnrollDialogClosed_">
+ </settings-security-keys-bio-enroll-dialog>
+ </template>
+
</template>
<script src="security_keys_subpage.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js
index b0eee4155a2..414f10740ec 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_subpage.js
@@ -21,6 +21,15 @@ Polymer({
},
/** @private */
+ enableBioEnrollment_: {
+ type: Boolean,
+ readOnly: true,
+ value: function() {
+ return loadTimeData.getBoolean('enableSecurityKeysBioEnrollment');
+ }
+ },
+
+ /** @private */
showSetPINDialog_: {
type: Boolean,
value: false,
@@ -35,6 +44,11 @@ Polymer({
type: Boolean,
value: false,
},
+ /** @private */
+ showBioEnrollDialog_: {
+ type: Boolean,
+ value: false,
+ },
},
/** @private */
@@ -56,7 +70,7 @@ Polymer({
/** @private */
onCredentialManagementDialogClosed_: function() {
this.showCredentialManagementDialog_ = false;
- cr.ui.focusWithoutInk(this.$.credentialManagementButton);
+ cr.ui.focusWithoutInk(assert(this.$$('#credentialManagementButton')));
},
/** @private */
@@ -69,4 +83,15 @@ Polymer({
this.showResetDialog_ = false;
cr.ui.focusWithoutInk(this.$.resetButton);
},
+
+ /** @private */
+ onBioEnroll_: function() {
+ this.showBioEnrollDialog_ = true;
+ },
+
+ /** @private */
+ onBioEnrollDialogClosed_: function() {
+ this.showBioEnrollDialog_ = false;
+ cr.ui.focusWithoutInk(assert(this.$$('#bioEnrollButton')));
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/route.js b/chromium/chrome/browser/resources/settings/route.js
index 808fc7775c4..244cb3be580 100644
--- a/chromium/chrome/browser/resources/settings/route.js
+++ b/chromium/chrome/browser/resources/settings/route.js
@@ -101,6 +101,7 @@
* SITE_SETTINGS_LOCATION: (undefined|!settings.Route),
* SITE_SETTINGS_MICROPHONE: (undefined|!settings.Route),
* SITE_SETTINGS_MIDI_DEVICES: (undefined|!settings.Route),
+ * SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE: (undefined|!settings.Route),
* SITE_SETTINGS_NOTIFICATIONS: (undefined|!settings.Route),
* SITE_SETTINGS_PAYMENT_HANDLER: (undefined|!settings.Route),
* SITE_SETTINGS_PDF_DOCUMENTS: (undefined|!settings.Route),
@@ -224,12 +225,10 @@ cr.define('settings', function() {
}
/**
- * Computes and return all available routes based on settings.pageVisibility.
- * @return {!SettingsRoutes}
+ * @return {!SettingsRoutes} Routes that are shared between browser and OS
+ * settings under the same conditions (e.g. in guest mode).
*/
- const computeAvailableRoutes = function() {
- const pageVisibility = settings.pageVisibility || {};
-
+ function computeCommonRoutes() {
/** @type {!SettingsRoutes} */
const r = {};
@@ -237,27 +236,33 @@ cr.define('settings', function() {
r.BASIC = new Route('/');
r.ABOUT = new Route('/help');
- // Navigable dialogs. These are the only non-section children of root
- // pages. These are disfavored. If we add anymore, we should add explicit
- // support.
- r.IMPORT_DATA = r.BASIC.createChild('/importData');
- r.IMPORT_DATA.isNavigableDialog = true;
r.SIGN_OUT = r.BASIC.createChild('/signOut');
r.SIGN_OUT.isNavigableDialog = true;
- // <if expr="chromeos">
- r.INTERNET = r.BASIC.createSection('/internet', 'internet');
- r.INTERNET_NETWORKS = r.INTERNET.createChild('/networks');
- r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail');
- r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks');
- r.BLUETOOTH = r.BASIC.createSection('/bluetooth', 'bluetooth');
- r.BLUETOOTH_DEVICES = r.BLUETOOTH.createChild('/bluetoothDevices');
+ r.SEARCH = r.BASIC.createSection('/search', 'search');
+ if (!loadTimeData.getBoolean('isGuest')) {
+ r.PEOPLE = r.BASIC.createSection('/people', 'people');
+ r.SYNC = r.PEOPLE.createChild('/syncSetup');
+ r.SYNC_ADVANCED = r.SYNC.createChild('/syncSetup/advanced');
+ }
+
+ return r;
+ }
- r.MULTIDEVICE = r.BASIC.createSection('/multidevice', 'multidevice');
- r.MULTIDEVICE_FEATURES = r.MULTIDEVICE.createChild('/multidevice/features');
- r.SMART_LOCK =
- r.MULTIDEVICE_FEATURES.createChild('/multidevice/features/smartLock');
+ /**
+ * Adds Route objects for each path corresponding to browser-only content.
+ * @param {!SettingsRoutes} r Routes to include browser-only content.
+ */
+ function addBrowserSettingsRoutes(r) {
+ const pageVisibility = settings.pageVisibility || {};
+
+ // <if expr="not chromeos">
+ r.IMPORT_DATA = r.BASIC.createChild('/importData');
+ r.IMPORT_DATA.isNavigableDialog = true;
+ if (pageVisibility.people !== false) {
+ r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile');
+ }
// </if>
if (pageVisibility.appearance !== false) {
@@ -277,84 +282,13 @@ cr.define('settings', function() {
r.BASIC.createSection('/defaultBrowser', 'defaultBrowser');
}
- r.SEARCH = r.BASIC.createSection('/search', 'search');
r.SEARCH_ENGINES = r.SEARCH.createChild('/searchEngines');
- // <if expr="chromeos">
- if (loadTimeData.valueExists('assistantEnabled') &&
- loadTimeData.getBoolean('assistantEnabled')) {
- r.GOOGLE_ASSISTANT = r.SEARCH.createChild('/googleAssistant');
- }
-
- if (loadTimeData.valueExists('showApps') &&
- loadTimeData.getBoolean('showApps')) {
- r.APPS = r.BASIC.createSection('/apps', 'apps');
- }
-
- r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps');
- r.ANDROID_APPS_DETAILS = r.ANDROID_APPS.createChild('/androidApps/details');
-
- if (loadTimeData.valueExists('showCrostini') &&
- loadTimeData.getBoolean('showCrostini')) {
- r.CROSTINI = r.BASIC.createSection('/crostini', 'crostini');
- r.CROSTINI_DETAILS = r.CROSTINI.createChild('/crostini/details');
- r.CROSTINI_EXPORT_IMPORT =
- r.CROSTINI_DETAILS.createChild('/crostini/exportImport');
- r.CROSTINI_SHARED_PATHS =
- r.CROSTINI_DETAILS.createChild('/crostini/sharedPaths');
- r.CROSTINI_SHARED_USB_DEVICES =
- r.CROSTINI_DETAILS.createChild('/crostini/sharedUsbDevices');
- }
-
- if (loadTimeData.valueExists('showPluginVm') &&
- loadTimeData.getBoolean('showPluginVm')) {
- r.PLUGIN_VM = r.BASIC.createSection('/pluginVm', 'pluginVm');
- r.PLUGIN_VM_DETAILS = r.PLUGIN_VM.createChild('/pluginVm/details');
- r.PLUGIN_VM_SHARED_PATHS =
- r.PLUGIN_VM.createChild('/pluginVm/sharedPaths');
- }
- // </if>
if (pageVisibility.onStartup !== false) {
r.ON_STARTUP = r.BASIC.createSection('/onStartup', 'onStartup');
r.STARTUP_PAGES = r.ON_STARTUP.createChild('/startupPages');
}
- if (pageVisibility.people !== false) {
- r.PEOPLE = r.BASIC.createSection('/people', 'people');
- r.SYNC = r.PEOPLE.createChild('/syncSetup');
- r.SYNC_ADVANCED = r.SYNC.createChild('/syncSetup/advanced');
- // <if expr="not chromeos">
- r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile');
- // </if>
- // <if expr="chromeos">
- // TODO(crbug.com/950007): Remove when SplitSettings is the default.
- if (loadTimeData.getBoolean('isOSSettings')) {
- r.PERSONALIZATION =
- r.BASIC.createSection('/personalization', 'personalization');
- r.CHANGE_PICTURE = r.PERSONALIZATION.createChild('/changePicture');
- } else {
- r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture');
- }
- r.ACCOUNTS = r.PEOPLE.createChild('/accounts');
- r.ACCOUNT_MANAGER = r.PEOPLE.createChild('/accountManager');
- r.KERBEROS_ACCOUNTS = r.PEOPLE.createChild('/kerberosAccounts');
- r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen');
- r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint');
- // </if>
- }
-
- // <if expr="chromeos">
- r.DEVICE = r.BASIC.createSection('/device', 'device');
- r.POINTERS = r.DEVICE.createChild('/pointer-overlay');
- r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay');
- r.STYLUS = r.DEVICE.createChild('/stylus');
- r.DISPLAY = r.DEVICE.createChild('/display');
- r.STORAGE = r.DEVICE.createChild('/storage');
- r.EXTERNAL_STORAGE_PREFERENCES =
- r.DEVICE.createChild('/storage/externalStoragePreferences');
- r.POWER = r.DEVICE.createChild('/power');
- // </if>
-
// Advanced Routes
if (pageVisibility.advancedSettings !== false) {
r.ADVANCED = new Route('/advanced');
@@ -422,48 +356,23 @@ cr.define('settings', function() {
r.SITE_SETTINGS_BLUETOOTH_SCANNING =
r.SITE_SETTINGS.createChild('bluetoothScanning');
}
-
- // <if expr="chromeos">
- if (pageVisibility.dateTime !== false) {
- r.DATETIME = r.ADVANCED.createSection('/dateTime', 'dateTime');
- r.DATETIME_TIMEZONE_SUBPAGE =
- r.DATETIME.createChild('/dateTime/timeZone');
+ if (loadTimeData.getBoolean(
+ 'enableNativeFileSystemWriteContentSetting')) {
+ r.SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE =
+ r.SITE_SETTINGS.createChild('filesystem');
}
- // </if>
r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages');
- // <if expr="chromeos">
- if (loadTimeData.getBoolean('isOSSettings')) {
- r.LANGUAGES_DETAILS = r.LANGUAGES.createChild('/languages/details');
- r.INPUT_METHODS =
- r.LANGUAGES_DETAILS.createChild('/languages/inputMethods');
- } else {
- r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods');
- }
- // </if>
// <if expr="not is_macosx">
r.EDIT_DICTIONARY = r.LANGUAGES.createChild('/editDictionary');
// </if>
if (pageVisibility.downloads !== false) {
r.DOWNLOADS = r.ADVANCED.createSection('/downloads', 'downloads');
- // <if expr="chromeos">
- // TODO(crbug.com/950007): Make unconditional and remove 'else' block
- // when SplitSettings is the default.
- if (loadTimeData.getBoolean('isOSSettings')) {
- r.FILES = r.ADVANCED.createSection('/files', 'files');
- r.SMB_SHARES = r.FILES.createChild('/smbShares');
- } else {
- r.SMB_SHARES = r.DOWNLOADS.createChild('/smbShares');
- }
- // </if>
}
r.PRINTING = r.ADVANCED.createSection('/printing', 'printing');
r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters');
- // <if expr="chromeos">
- r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters');
- // </if>
r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y');
@@ -480,19 +389,9 @@ cr.define('settings', function() {
}
// </if>
- // <if expr="chromeos">
- r.MANAGE_ACCESSIBILITY =
- r.ACCESSIBILITY.createChild('/manageAccessibility');
- if (loadTimeData.getBoolean(
- 'showExperimentalAccessibilitySwitchAccess')) {
- r.MANAGE_SWITCH_ACCESS_SETTINGS = r.MANAGE_ACCESSIBILITY.createChild(
- '/manageAccessibility/switchAccess');
- }
- r.MANAGE_TTS_SETTINGS =
- r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts');
- // </if>
-
+ // <if expr="not chromeos">
r.SYSTEM = r.ADVANCED.createSection('/system', 'system');
+ // </if>
if (pageVisibility.reset !== false) {
r.RESET = r.ADVANCED.createSection('/reset', 'reset');
@@ -510,28 +409,182 @@ cr.define('settings', function() {
// </if>
}
}
+ }
+
+ // <if expr="chromeos">
+ /**
+ * Adds Route objects for each path corresponding to CrOS-only content.
+ * @param {!SettingsRoutes} r Routes to include CrOS-only content.
+ */
+ function addOSSettingsRoutes(r) {
+ r.INTERNET = r.BASIC.createSection('/internet', 'internet');
+ r.INTERNET_NETWORKS = r.INTERNET.createChild('/networks');
+ r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail');
+ r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks');
+ r.BLUETOOTH = r.BASIC.createSection('/bluetooth', 'bluetooth');
+ r.BLUETOOTH_DEVICES = r.BLUETOOTH.createChild('/bluetoothDevices');
+
+ r.DEVICE = r.BASIC.createSection('/device', 'device');
+ r.POINTERS = r.DEVICE.createChild('/pointer-overlay');
+ r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay');
+ r.STYLUS = r.DEVICE.createChild('/stylus');
+ r.DISPLAY = r.DEVICE.createChild('/display');
+ r.STORAGE = r.DEVICE.createChild('/storage');
+ r.EXTERNAL_STORAGE_PREFERENCES =
+ r.DEVICE.createChild('/storage/externalStoragePreferences');
+ r.POWER = r.DEVICE.createChild('/power');
- // <if expr="chromeos">
// "About" is the only section in About, but we still need to create the
// route in order to show the subpage on Chrome OS.
r.ABOUT_ABOUT = r.ABOUT.createSection('/help/about', 'about');
- // TODO(aee): Remove once this file is forked.
- if (loadTimeData.getBoolean('showOSSettings')) {
- r.DETAILED_BUILD_INFO = r.ABOUT_ABOUT.createChild('/help/details');
+ r.DETAILED_BUILD_INFO = r.ABOUT_ABOUT.createChild('/help/details');
+
+ if (!loadTimeData.getBoolean('isGuest')) {
+ r.MULTIDEVICE = r.BASIC.createSection('/multidevice', 'multidevice');
+ r.MULTIDEVICE_FEATURES =
+ r.MULTIDEVICE.createChild('/multidevice/features');
+ r.SMART_LOCK =
+ r.MULTIDEVICE_FEATURES.createChild('/multidevice/features/smartLock');
+
+ r.ACCOUNTS = r.PEOPLE.createChild('/accounts');
+ r.ACCOUNT_MANAGER = r.PEOPLE.createChild('/accountManager');
+ r.KERBEROS_ACCOUNTS = r.PEOPLE.createChild('/kerberosAccounts');
+ r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen');
+ r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint');
}
- // </if>
- return r;
- };
+ if (loadTimeData.valueExists('androidAppsVisible') &&
+ loadTimeData.getBoolean('androidAppsVisible')) {
+ r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps');
+ r.ANDROID_APPS_DETAILS =
+ r.ANDROID_APPS.createChild('/androidApps/details');
+ }
+
+ if (loadTimeData.valueExists('showCrostini') &&
+ loadTimeData.getBoolean('showCrostini')) {
+ r.CROSTINI = r.BASIC.createSection('/crostini', 'crostini');
+ r.CROSTINI_DETAILS = r.CROSTINI.createChild('/crostini/details');
+ if (loadTimeData.valueExists('showCrostiniExportImport') &&
+ loadTimeData.getBoolean('showCrostiniExportImport')) {
+ r.CROSTINI_EXPORT_IMPORT =
+ r.CROSTINI_DETAILS.createChild('/crostini/exportImport');
+ }
+ r.CROSTINI_SHARED_PATHS =
+ r.CROSTINI_DETAILS.createChild('/crostini/sharedPaths');
+ r.CROSTINI_SHARED_USB_DEVICES =
+ r.CROSTINI_DETAILS.createChild('/crostini/sharedUsbDevices');
+ }
+
+ if (loadTimeData.valueExists('showPluginVm') &&
+ loadTimeData.getBoolean('showPluginVm')) {
+ r.PLUGIN_VM = r.BASIC.createSection('/pluginVm', 'pluginVm');
+ r.PLUGIN_VM_DETAILS = r.PLUGIN_VM.createChild('/pluginVm/details');
+ r.PLUGIN_VM_SHARED_PATHS =
+ r.PLUGIN_VM.createChild('/pluginVm/sharedPaths');
+ }
+
+ r.GOOGLE_ASSISTANT = r.SEARCH.createChild('/googleAssistant');
+
+ // This if/else accounts for sections that were added or refactored in
+ // the settings split (crbug.com/950007) and some routes that were created
+ // in browser settings conditioned on the pageVisibility constant, which is
+ // being decoupled from OS Settings in the split. The 'else' block provides
+ // a section-by-section comparison.
+ // TODO (crbug.com/967861): Make 'if' block unconditional. Remove 'else'
+ // block.
+ if (loadTimeData.getBoolean('isOSSettings')) {
+ r.ADVANCED = new Route('/advanced');
+
+ r.PRIVACY = r.ADVANCED.createSection('/privacy', 'privacy');
+
+ // Languages and input
+ r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages');
+ r.LANGUAGES_DETAILS = r.LANGUAGES.createChild('/languages/details');
+ r.INPUT_METHODS =
+ r.LANGUAGES_DETAILS.createChild('/languages/inputMethods');
+
+ r.PRINTING = r.ADVANCED.createSection('/printing', 'printing');
+
+ r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y');
+
+ if (!loadTimeData.getBoolean('isGuest')) {
+ // Personalization
+ r.PERSONALIZATION =
+ r.BASIC.createSection('/personalization', 'personalization');
+ r.CHANGE_PICTURE = r.PERSONALIZATION.createChild('/changePicture');
+
+ // Files (analogous to Downloads)
+ r.FILES = r.ADVANCED.createSection('/files', 'files');
+ r.SMB_SHARES = r.FILES.createChild('/smbShares');
+ }
+
+ // Reset
+ if (loadTimeData.valueExists('allowPowerwash') &&
+ loadTimeData.getBoolean('allowPowerwash')) {
+ r.RESET = r.ADVANCED.createSection('/reset', 'reset');
+ }
+
+ // Apps
+ if (loadTimeData.valueExists('showApps') &&
+ loadTimeData.getBoolean('showApps')) {
+ r.APPS = r.BASIC.createSection('/apps', 'apps');
+ r.APP_MANAGEMENT = r.APPS.createChild('/app-management');
+ r.APP_MANAGEMENT_DETAIL =
+ r.APP_MANAGEMENT.createChild('/app-management/detail');
+ }
+ } else {
+ assert(r.ADVANCED, 'ADVANCED route should exist');
+
+ assert(r.PRIVACY, 'PRIVACY route should exist');
+
+ // Languages and input
+ assert(r.LANGUAGES, 'LANGUAGES route should exist');
+ r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods');
+
+ assert(r.PRINTING, 'PRINTING route should exist');
+
+ assert(r.ACCESSIBILITY, 'ACCESSIBILITY route should exist');
+
+ if (!loadTimeData.getBoolean('isGuest')) {
+ // People
+ r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture');
+
+ // Downloads (analogous to Files)
+ assert(r.DOWNLOADS, 'DOWNLOADS route should exist');
+ r.SMB_SHARES = r.DOWNLOADS.createChild('/smbShares');
+
+ // Reset
+ assert(r.RESET, 'RESET route should exist');
+ }
+
+ assert(!r.APPS, 'APPS route should not exist');
+ }
+
+ r.DATETIME = r.ADVANCED.createSection('/dateTime', 'dateTime');
+ r.DATETIME_TIMEZONE_SUBPAGE = r.DATETIME.createChild('/dateTime/timeZone');
+
+ r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters');
+
+ r.MANAGE_ACCESSIBILITY =
+ r.ACCESSIBILITY.createChild('/manageAccessibility');
+ if (loadTimeData.getBoolean('showExperimentalAccessibilitySwitchAccess')) {
+ r.MANAGE_SWITCH_ACCESS_SETTINGS = r.MANAGE_ACCESSIBILITY.createChild(
+ '/manageAccessibility/switchAccess');
+ }
+ r.MANAGE_TTS_SETTINGS =
+ r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts');
+ }
+ // </if>
class Router {
- constructor() {
+ /** @param {!SettingsRoutes} availableRoutes */
+ constructor(availableRoutes) {
/**
* List of available routes. This is populated taking into account current
* state (like guest mode).
* @private {!SettingsRoutes}
*/
- this.routes_ = computeAvailableRoutes();
+ this.routes_ = availableRoutes;
/**
* The current active route. This updated is only by settings.navigateTo
@@ -710,7 +763,31 @@ cr.define('settings', function() {
}
}
- const routerInstance = new Router();
+ /**
+ * @return {!settings.Router} A router with at least those routes common to OS
+ * and browser settings. If the window is not in OS settings (based on
+ * loadTimeData) then browser specific routes are added. If the window is
+ * OS settings or if Chrome OS is using a consolidated settings page for
+ * OS and browser settings then OS specific routes are added.
+ */
+ function buildRouter() {
+ const availableRoutes = computeCommonRoutes();
+ const isOSSettings = loadTimeData.valueExists('isOSSettings') &&
+ loadTimeData.getBoolean('isOSSettings');
+ if (!isOSSettings) {
+ addBrowserSettingsRoutes(availableRoutes);
+ }
+
+ // <if expr="chromeos">
+ const showOSSettings = loadTimeData.valueExists('showOSSettings') &&
+ loadTimeData.getBoolean('showOSSettings');
+ if (isOSSettings || showOSSettings) {
+ addOSSettingsRoutes(availableRoutes);
+ }
+ // </if>
+ return new Router(availableRoutes);
+ }
+ const routerInstance = buildRouter();
const routeObservers = new Set();
@@ -780,6 +857,7 @@ cr.define('settings', function() {
Route: Route, // The Route class definition.
Router: Router, // The Router class definition.
router: routerInstance, // the singleton.
+ buildRouterForTesting: buildRouter,
routes: routes,
RouteObserverBehavior: RouteObserverBehavior,
getRouteForPath: getRouteForPath,
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html
index 43fcdba764a..fac0773366c 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html
@@ -25,7 +25,7 @@
</style>
<div class="list-item" focus-row-container>
<div class="name-column">
- <site-favicon url="[[engine.iconURL]]"></site-favicon>
+ <site-favicon favicon-url="[[engine.iconURL]]"></site-favicon>
<span>[[engine.displayName]]</span>
</div>
<div class="keyword-column">[[engine.keyword]]</div>
diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
index 9715c76b469..83d8b346ed4 100644
--- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
+++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
@@ -41,7 +41,7 @@
<div class="list-item" focus-row-container>
<div id="name-column">
- <site-favicon url="[[engine.iconURL]]"></site-favicon>
+ <site-favicon favicon-url="[[engine.iconURL]]"></site-favicon>
<div>[[engine.displayName]]</div>
</div>
<div id="keyword-column"><div>[[engine.keyword]]</div></div>
diff --git a/chromium/chrome/browser/resources/settings/search_settings.js b/chromium/chrome/browser/resources/settings/search_settings.js
index 98d79796f44..a98f501303f 100644
--- a/chromium/chrome/browser/resources/settings/search_settings.js
+++ b/chromium/chrome/browser/resources/settings/search_settings.js
@@ -153,7 +153,7 @@ cr.define('settings', function() {
parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
parent.host :
parent.parentNode;
- if (parent.nodeName == 'SETTINGS-SUBPAGE') {
+ if (parent && parent.nodeName == 'SETTINGS-SUBPAGE') {
// TODO(dpapad): Cast to SettingsSubpageElement here.
associatedControl = assert(
parent.associatedControl,
diff --git a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
index d75f667d3c3..b005a754146 100644
--- a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -63,7 +63,6 @@
<template is="dom-if" if="[[showPages_.settings]]">
<settings-basic-page prefs="{{prefs}}"
page-visibility="[[pageVisibility]]"
- show-apps="[[showApps]]"
show-android-apps="[[showAndroidApps]]"
show-crostini="[[showCrostini]]"
show-parental-controls="[[showParentalControls]]"
diff --git a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
index 9369f5f5517..4dabc3f833b 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -10,6 +10,11 @@
<link rel="import" href="../route.html">
<link rel="import" href="../settings_shared_css.html">
+<if expr="chromeos">
+<!-- TODO(crbug.com/986596): Remove OS icons when SplitSettings is complete. -->
+<link rel="import" href="../chromeos/os_icons.html">
+</if>
+
<dom-module id="settings-menu">
<template>
<style include="settings-shared">
@@ -107,7 +112,7 @@
role="navigation" on-click="onLinkClick_">
<if expr="chromeos">
<a href="/internet" hidden="[[!pageVisibility.internet]]">
- <iron-icon icon="settings:network-wifi"></iron-icon>
+ <iron-icon icon="os-settings:network-wifi"></iron-icon>
$i18n{internetPageTitle}
</a>
<a href="/bluetooth" hidden="[[!pageVisibility.bluetooth]]">
@@ -116,7 +121,7 @@
</a>
<a id="multidevice" href="/multidevice"
hidden="[[!pageVisibility.multidevice]]">
- <iron-icon icon="settings:multidevice-better-together-suite">
+ <iron-icon icon="os-settings:multidevice-better-together-suite">
</iron-icon>
$i18n{multidevicePageTitle}
</a>
@@ -137,7 +142,7 @@
</a>
<if expr="chromeos">
<a href="/device" hidden="[[!pageVisibility.device]]">
- <iron-icon icon="settings:laptop-chromebook"></iron-icon>
+ <iron-icon icon="os-settings:laptop-chromebook"></iron-icon>
$i18n{devicePageTitle}
</a>
</if>
@@ -146,20 +151,16 @@
$i18n{searchPageTitle}
</a>
<if expr="chromeos">
- <a href="/apps" hidden="[[!showApps]]">
- <iron-icon icon="settings:apps"></iron-icon>
- $i18n{appsPageTitle}
- </a>
<a href="/androidApps" hidden="[[!showAndroidApps]]">
- <iron-icon icon="settings:play-prism"></iron-icon>
+ <iron-icon icon="os-settings:play-prism"></iron-icon>
$i18n{androidAppsPageTitle}
</a>
<a href="/crostini" hidden="[[!showCrostini]]">
- <iron-icon icon="settings:crostini-mascot"></iron-icon>
+ <iron-icon icon="os-settings:crostini-mascot"></iron-icon>
$i18n{crostiniPageTitle}
</a>
<a href="/pluginVm" hidden="[[!showPluginVm]]">
- <iron-icon icon="settings:plugin-vm"></iron-icon>
+ <iron-icon icon="os-settings:plugin-vm"></iron-icon>
$i18n{pluginVmPageTitle}
</a>
</if>
@@ -187,7 +188,7 @@
role="navigation" on-click="onLinkClick_">
<if expr="chromeos">
<a href="/dateTime" hidden="[[!pageVisibility.dateTime]]">
- <iron-icon icon="settings:access-time"></iron-icon>
+ <iron-icon icon="os-settings:access-time"></iron-icon>
$i18n{dateTimePageTitle}
</a>
</if>
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html
index 4989fb87e41..c48064bcaf2 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -45,6 +45,13 @@
width: var(--cr-icon-ripple-size);
}
+ #title-icon {
+ height: 36px;
+ margin-inline-end: 12px;
+ margin-inline-start: 2px;
+ width: 36px;
+ }
+
cr-icon-button {
/* Centers the ripple on the icon with appropriate margin on right. */
margin-inline-end: 10px;
@@ -67,6 +74,9 @@
<div class="settings-box first" id="headerLine">
<cr-icon-button class="icon-arrow-back" id="closeButton"
on-click="onTapBack_" aria-label="$i18n{back}"></cr-icon-button>
+ <template is="dom-if" if="[[titleIcon]]">
+ <img id="title-icon" src="[[titleIcon]]">
+ </template>
<h1 class="cr-title-text">[[pageTitle]]</h1>
<slot name="subpage-title-extra"></slot>
<template is="dom-if" if="[[learnMoreUrl]]">
diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.js b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.js
index b33ba416d65..bea0032426f 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.js
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.js
@@ -20,6 +20,8 @@ Polymer({
properties: {
pageTitle: String,
+ titleIcon: String,
+
learnMoreUrl: String,
/** Setting a |searchLabel| will enable search. */
diff --git a/chromium/chrome/browser/resources/settings/settings_resources.grd b/chromium/chrome/browser/resources/settings/settings_resources.grd
index f9f460935ef..14f631a9af7 100644
--- a/chromium/chrome/browser/resources/settings/settings_resources.grd
+++ b/chromium/chrome/browser/resources/settings/settings_resources.grd
@@ -151,6 +151,14 @@
file="appearance_page/appearance_browser_proxy.js"
type="chrome_html"
preprocess="true" />
+ <if expr="chromeos">
+ <structure name="IDR_SETTINGS_WALLPAPER_BROWSER_PROXY_HTML"
+ file="appearance_page/wallpaper_browser_proxy.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_WALLPAPER_BROWSER_PROXY_JS"
+ file="appearance_page/wallpaper_browser_proxy.js"
+ type="chrome_html" />
+ </if>
<structure name="IDR_SETTINGS_APPEARANCE_FONTS_PAGE_HTML"
file="appearance_page/appearance_fonts_page.html"
type="chrome_html"
@@ -416,6 +424,12 @@
<structure name="IDR_SETTINGS_SECURITY_KEYS_RESET_DIALOG_JS"
file="privacy_page/security_keys_reset_dialog.js"
type="chrome_html"/>
+ <structure name="IDR_SETTINGS_SECURITY_KEYS_BIO_ENROLL_DIALOG_HTML"
+ file="privacy_page/security_keys_bio_enroll_dialog.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_SECURITY_KEYS_BIO_ENROLL_DIALOG_JS"
+ file="privacy_page/security_keys_bio_enroll_dialog.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_SECURITY_KEYS_DIALOG_BROWSER_PROXY_HTML"
file="privacy_page/security_keys_browser_proxy.html"
type="chrome_html" />
@@ -573,6 +587,12 @@
<structure name="IDR_SETTINGS_DEVICE_STORAGE_JS"
file="device_page/storage.js"
type="chrome_html" />
+ <structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_ENTRY_HTML"
+ file="device_page/storage_external_entry.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_ENTRY_JS"
+ file="device_page/storage_external_entry.js"
+ type="chrome_html" />
<structure name="IDR_SETTINGS_DEVICE_STORAGE_EXTERNAL_HTML"
file="device_page/storage_external.html"
type="chrome_html" />
@@ -647,6 +667,14 @@
file="icons.html"
type="chrome_html"
preprocess="true" />
+ <if expr="chromeos">
+ <!-- TODO(crbug.com/986596): Remove OS icons when SplitSettings
+ is complete. -->
+ <structure name="IDR_SETTINGS_CHROMEOS_OS_ICONS"
+ file="chromeos/os_icons.html"
+ type="chrome_html"
+ preprocess="true" />
+ </if>
<structure name="IDR_SETTINGS_POWERWASH_DIALOG_HTML"
file="reset_page/powerwash_dialog.html"
type="chrome_html" />
@@ -1300,12 +1328,6 @@
file="site_settings/zoom_levels.js"
type="chrome_html" />
<if expr="chromeos">
- <structure name="IDR_SETTINGS_APP_MANAGEMENT_PAGE_HTML"
- file="app_management_page/app_management_page.html"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_APP_MANAGEMENT_PAGE_JS"
- file="app_management_page/app_management_page.js"
- type="chrome_html" />
<structure name="IDR_SETTINGS_ANDROID_APPS_PAGE_HTML"
file="android_apps_page/android_apps_page.html"
type="chrome_html" />
diff --git a/chromium/chrome/browser/resources/settings/settings_shared_css.html b/chromium/chrome/browser/resources/settings/settings_shared_css.html
index bc22b45af3c..f91bdedd09b 100644
--- a/chromium/chrome/browser/resources/settings/settings_shared_css.html
+++ b/chromium/chrome/browser/resources/settings/settings_shared_css.html
@@ -186,6 +186,13 @@
min-height: inherit;
}
+ /* Link buttons use FocusOutlineManager to only show outlines when focus
+ * was triggered by keyboard. */
+ :host-context(html:not(.focus-outline-visible))
+ .list-button[is='action-link'] {
+ outline: none;
+ }
+
/* A row with two lines of text. Often the lower line will be .secondary.
*/
.two-line {
diff --git a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
index 9d42840497d..286257d15ea 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -43,7 +43,6 @@
cr-toolbar {
@apply --layout-center;
min-height: 56px;
- z-index: 2;
--cr-toolbar-left-spacer-width: var(--settings-menu-width);
--cr-toolbar-center-basis: var(--settings-main-basis);
}
@@ -126,7 +125,6 @@
<div class="drawer-content">
<template is="dom-if" id="drawerTemplate">
<settings-menu page-visibility="[[pageVisibility_]]"
- show-apps="[[showApps_]]"
show-android-apps="[[showAndroidApps_]]"
show-crostini="[[showCrostini_]]"
show-parental-controls="[[showParentalControls_]]"
@@ -141,7 +139,6 @@
<div id="container" class="no-outline">
<div id="left">
<settings-menu page-visibility="[[pageVisibility_]]"
- show-apps="[[showApps_]]"
show-android-apps="[[showAndroidApps_]]"
show-crostini="[[showCrostini_]]"
show-parental-controls="[[showParentalControls_]]"
diff --git a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
index f3868ee260e..fdbbef286d5 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -66,9 +66,6 @@ Polymer({
pageVisibility_: {type: Object, value: settings.pageVisibility},
/** @private */
- showApps_: Boolean,
-
- /** @private */
showAndroidApps_: Boolean,
/** @private */
@@ -147,7 +144,6 @@ Polymer({
OncTypeTether: loadTimeData.getString('OncTypeTether'),
OncTypeVPN: loadTimeData.getString('OncTypeVPN'),
OncTypeWiFi: loadTimeData.getString('OncTypeWiFi'),
- OncTypeWiMAX: loadTimeData.getString('OncTypeWiMAX'),
networkListItemConnected:
loadTimeData.getString('networkListItemConnected'),
networkListItemConnecting:
@@ -169,8 +165,6 @@ Polymer({
// The SplitSettings feature hides OS settings in the browser settings page.
// https://crbug.com/950007
const showOSSettings = loadTimeData.getBoolean('showOSSettings');
- this.showApps_ = showOSSettings && loadTimeData.valueExists('showApps') &&
- loadTimeData.getBoolean('showApps');
this.showAndroidApps_ = showOSSettings &&
loadTimeData.valueExists('androidAppsVisible') &&
loadTimeData.getBoolean('androidAppsVisible');
diff --git a/chromium/chrome/browser/resources/settings/site_favicon.html b/chromium/chrome/browser/resources/settings/site_favicon.html
index 7ff3ca780bd..0b99dc90c3e 100644
--- a/chromium/chrome/browser/resources/settings/site_favicon.html
+++ b/chromium/chrome/browser/resources/settings/site_favicon.html
@@ -5,7 +5,7 @@
<dom-module id="site-favicon">
<template>
<style>
- :host {
+ #favicon {
background-repeat: no-repeat;
background-size: contain;
display: block;
@@ -13,6 +13,10 @@
width: 16px;
}
</style>
+ <div
+ id="favicon"
+ style="background-image: [[getBackgroundImage_(faviconUrl, url)]]">
+ </div>
</template>
<script src="site_favicon.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_favicon.js b/chromium/chrome/browser/resources/settings/site_favicon.js
index 09f30efc673..e905bd54e35 100644
--- a/chromium/chrome/browser/resources/settings/site_favicon.js
+++ b/chromium/chrome/browser/resources/settings/site_favicon.js
@@ -11,18 +11,22 @@ Polymer({
is: 'site-favicon',
properties: {
- url: {
- type: String,
- value: '',
- observer: 'urlChanged_',
- }
+ faviconUrl: String,
+ url: String,
},
/** @private */
- urlChanged_: function() {
- let url = this.removePatternWildcard_(this.url);
- url = this.ensureUrlHasScheme_(url);
- this.style.backgroundImage = cr.icon.getFavicon(url || '', false);
+ getBackgroundImage_: function() {
+ let backgroundImage = 'none';
+ if (this.faviconUrl) {
+ const url = this.ensureUrlHasScheme_(this.faviconUrl);
+ backgroundImage = cr.icon.getFavicon(url);
+ } else if (this.url) {
+ let url = this.removePatternWildcard_(this.url);
+ url = this.ensureUrlHasScheme_(url);
+ backgroundImage = cr.icon.getFaviconForPageURL(url || '', false);
+ }
+ return backgroundImage;
},
/**
diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js b/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js
index 12f8c830dbc..554bc6992dc 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js
@@ -126,6 +126,7 @@ Polymer({
case settings.ContentSettingsTypes.USB_DEVICES:
case settings.ContentSettingsTypes.SERIAL_PORTS:
case settings.ContentSettingsTypes.BLUETOOTH_SCANNING:
+ case settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE:
// "Ask" vs "Blocked".
this.browserProxy.setDefaultValueForContentType(
this.category,
diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
index 5164f1ceb8d..01d7cb15355 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html
@@ -10,7 +10,8 @@
category-subtype="[[ContentSetting.BLOCK]]"
category-header="[[blockHeader]]"
read-only-list="[[readOnlyList]]"
- search-filter="[[searchFilter]]">
+ search-filter="[[searchFilter]]"
+ hidden$="[[!showBlockSiteList_]]">
</site-list>
<site-list
category="[[category]]"
@@ -24,7 +25,8 @@
category-subtype="[[ContentSetting.ALLOW]]"
category-header="$i18n{siteSettingsAllow}"
read-only-list="[[readOnlyList]]"
- search-filter="[[searchFilter]]">
+ search-filter="[[searchFilter]]"
+ hidden$="[[!showAllowSiteList_]]">
</site-list>
</template>
<script src="category_setting_exceptions.js"></script>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js
index bff5aae0f21..212204450a9 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js
@@ -11,6 +11,14 @@ Polymer({
is: 'category-setting-exceptions',
properties: {
+
+ /**
+ * The string ID of the category that this element is displaying data for.
+ * See site_settings/constants.js for possible values.
+ * @type {!settings.ContentSettingsTypes}
+ */
+ category: String,
+
/**
* Some content types (like Location) do not allow the user to manually
* edit the exception list from within Settings.
@@ -27,10 +35,38 @@ Polymer({
blockHeader: String,
searchFilter: String,
+
+ /**
+ * If true, displays the Allow site list. Defaults to true.
+ * @private
+ */
+ showAllowSiteList_: {
+ type: Boolean,
+ computed: 'computeShowAllowSiteList_(category)',
+ },
+
+ /**
+ * If true, displays the Block site list. Defaults to true.
+ */
+ showBlockSiteList_: {
+ type: Boolean,
+ value: true,
+ },
},
/** @override */
ready: function() {
this.ContentSetting = settings.ContentSetting;
},
+
+ /**
+ * Hides particular category subtypes if |this.category| does not support the
+ * content setting of that type.
+ * @return {boolean}
+ * @private
+ */
+ computeShowAllowSiteList_: function() {
+ return this.category !=
+ settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE;
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/site_settings/constants.js b/chromium/chrome/browser/resources/settings/site_settings/constants.js
index 909b06ff3b4..a7cf78b84ad 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/constants.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/constants.js
@@ -37,6 +37,7 @@ settings.ContentSettingsTypes = {
SENSORS: 'sensors',
PAYMENT_HANDLER: 'payment-handler',
BLUETOOTH_SCANNING: 'bluetooth-scanning',
+ NATIVE_FILE_SYSTEM_WRITE: 'native-file-system-write',
};
/**
diff --git a/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js b/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js
index d4aec05be80..91289e40b9e 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js
@@ -53,10 +53,6 @@ const cookieInfo = {
['origin', 'fileSystemOrigin'], ['persistent', 'fileSystemPersistentUsage'],
['temporary', 'fileSystemTemporaryUsage']
],
- 'channel_id': [
- ['serverId', 'channelIdServerId'], ['certType', 'channelIdType'],
- ['created', 'channelIdCreated']
- ],
'service_worker':
[['origin', 'serviceWorkerOrigin'], ['size', 'serviceWorkerSize']],
'shared_worker':
diff --git a/chromium/chrome/browser/resources/settings/site_settings/local_data_browser_proxy.js b/chromium/chrome/browser/resources/settings/site_settings/local_data_browser_proxy.js
index dee64f793b3..56112da2884 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/local_data_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/local_data_browser_proxy.js
@@ -97,6 +97,14 @@ cr.define('settings', function() {
* @param {string} path The path to the parent cookie.
*/
removeCookie(path) {}
+
+ /**
+ * Removes all SameSite=None cookies, as well as storage available in
+ * third-party contexts.
+ * Note: on-tree-item-removed will not be sent.
+ * @return {!Promise} To signal completion.
+ */
+ removeAllThirdPartyCookies() {}
}
/**
@@ -142,6 +150,11 @@ cr.define('settings', function() {
removeCookie(path) {
chrome.send('localData.removeCookie', [path]);
}
+
+ /** @override */
+ removeAllThirdPartyCookies() {
+ return cr.sendWithPromise('localData.removeThirdPartyCookies');
+ }
}
// The singleton instance_ is replaced with a test version of this wrapper
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data.html b/chromium/chrome/browser/resources/settings/site_settings/site_data.html
index b3c8d9bf131..9fc485db610 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_data.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.html
@@ -42,6 +42,11 @@
on-click="onRemoveShowingSitesTap_" hidden$="[[!sites.length]]">
[[computeRemoveLabel_(filter)]]
</cr-button>
+ <cr-button disabled$="[[isLoading_]]" id="removeThirdPartyCookies"
+ on-click="onRemoveThirdPartyCookiesTap_"
+ hidden$="[[!enableRemovingAllThirdPartyCookies_]]">
+ $i18n{siteSettingsCookieRemoveAllThirdParty}
+ </cr-button>
</div>
<iron-list id="list" items="[[sites]]" preserve-focus
scroll-target="[[subpageScrollTarget]]" class="cr-separators">
@@ -71,6 +76,26 @@
</cr-button>
</div>
</cr-dialog>
+
+ <!-- Confirm Delete Third Party Cookies dialog -->
+ <cr-dialog id="confirmDeleteThirdPartyDialog" close-text="$i18n{close}"
+ on-close="onConfirmDeleteThirdPartyDialogClosed_">
+ <div slot="title">
+ $i18n{siteSettingsCookieRemoveThirdPartyDialogTitle}
+ </div>
+ <div slot="body">
+ $i18n{siteSettingsCookieRemoveThirdPartyConfirmation}
+ </div>
+ <div slot="button-container">
+ <cr-button class="cancel-button" on-click="onCloseThirdPartyDialog_">
+ $i18n{cancel}
+ </cr-button>
+ <cr-button class="action-button" on-click="onConfirmThirdPartyDelete_">
+ $i18n{siteSettingsCookiesClearThirdParty}
+ </cr-button>
+ </div>
+ </cr-dialog>
+
</template>
<script src="site_data.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data.js b/chromium/chrome/browser/resources/settings/site_settings/site_data.js
index 06c8e742b30..644aedc4ac0 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_data.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.js
@@ -75,6 +75,15 @@ Polymer({
/** @private */
listBlurred_: Boolean,
+
+ /** @private */
+ enableRemovingAllThirdPartyCookies_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('enableRemovingAllThirdPartyCookies') &&
+ (this.sites.length > 0);
+ }
+ },
},
/** @private {settings.LocalDataBrowserProxy} */
@@ -201,10 +210,20 @@ Polymer({
},
/** @private */
+ onCloseThirdPartyDialog_: function() {
+ this.$.confirmDeleteThirdPartyDialog.close();
+ },
+
+ /** @private */
onConfirmDeleteDialogClosed_: function() {
cr.ui.focusWithoutInk(assert(this.$.removeShowingSites));
},
+ /** @private */
+ onConfirmDeleteThirdPartyDialogClosed_: function() {
+ cr.ui.focusWithoutInk(assert(this.$.removeAllThirdPartyCookies));
+ },
+
/**
* Shows a dialog to confirm the deletion of multiple sites.
* @param {!Event} e
@@ -216,6 +235,16 @@ Polymer({
},
/**
+ * Shows a dialog to confirm the deletion of cookies available
+ * in third-party contexts and associated site data.
+ * @private
+ */
+ onRemoveThirdPartyCookiesTap_: function(e) {
+ e.preventDefault();
+ this.$.confirmDeleteThirdPartyDialog.showModal();
+ },
+
+ /**
* Called when deletion for all showing sites has been confirmed.
* @private
*/
@@ -233,6 +262,18 @@ Polymer({
},
/**
+ * Called when deletion of all third-party cookies and site data has been
+ * confirmed.
+ * @private
+ */
+ onConfirmThirdPartyDelete_: function() {
+ this.$.confirmDeleteThirdPartyDialog.close();
+ this.browserProxy_.removeAllThirdPartyCookies().then(() => {
+ this.updateSiteList_();
+ });
+ },
+
+ /**
* @param {!{model: !{item: CookieDataSummaryItem, index: number}}} event
* @private
*/
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js b/chromium/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
index f862bba40e6..37ca12214f4 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
@@ -8,7 +8,6 @@
const categoryLabels = {
app_cache: loadTimeData.getString('cookieAppCache'),
cache_storage: loadTimeData.getString('cookieCacheStorage'),
- channel_id: loadTimeData.getString('cookieChannelId'),
database: loadTimeData.getString('cookieDatabaseStorage'),
file_system: loadTimeData.getString('cookieFileSystem'),
flash_lso: loadTimeData.getString('cookieFlashLso'),
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.html b/chromium/chrome/browser/resources/settings/site_settings/site_details.html
index 5b373ff071c..1472652cc9e 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.html
@@ -178,6 +178,13 @@
label="$i18n{siteSettingsSerialPorts}">
</site-details-permission>
</template>
+ <template is="dom-if" if="[[enableNativeFileSystemWriteContentSetting_]]">
+ <site-details-permission
+ category="{{ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE}}"
+ icon="settings:save-original" id="nativeFileSystemWrite"
+ label="$i18n{siteSettingsNativeFileSystemWrite}">
+ </site-details-permission>
+ </template>
<site-details-permission
category="{{ContentSettingsTypes.UNSANDBOXED_PLUGINS}}"
icon="cr:extension" id="unsandboxedPlugins"
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.js b/chromium/chrome/browser/resources/settings/site_settings/site_details.js
index da034ee588f..875533a5f19 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_details.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.js
@@ -69,6 +69,15 @@ Polymer({
return loadTimeData.getBoolean('enableBluetoothScanningContentSetting');
}
},
+
+ /** @private */
+ enableNativeFileSystemWriteContentSetting_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean(
+ 'enableNativeFileSystemWriteContentSetting');
+ }
+ },
},
listeners: {
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js
index 88b55c9ce59..76f870645d2 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -230,7 +230,8 @@ Polymer({
return !(
category == settings.ContentSettingsTypes.SERIAL_PORTS ||
category == settings.ContentSettingsTypes.USB_DEVICES ||
- category == settings.ContentSettingsTypes.BLUETOOTH_SCANNING);
+ category == settings.ContentSettingsTypes.BLUETOOTH_SCANNING ||
+ category == settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE);
},
/**
@@ -248,8 +249,10 @@ Polymer({
return true;
}
- // For Bluetooth scanning permission 'ask' takes the place of 'allow'.
- if (category == settings.ContentSettingsTypes.BLUETOOTH_SCANNING) {
+ // For Bluetooth scanning permission and Native File System write permission
+ // 'ask' takes the place of 'allow'.
+ if (category == settings.ContentSettingsTypes.BLUETOOTH_SCANNING ||
+ category == settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE) {
return true;
}
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.html b/chromium/chrome/browser/resources/settings/site_settings/site_list.html
index a07b8c00068..de095c0574e 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_list.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.html
@@ -33,7 +33,7 @@
<div class="settings-box first">
<h2 class="start">[[categoryHeader]]</h2>
<cr-button id="addSite" class="header-aligned-button"
- hidden="[[readOnlyList]]" on-click="onAddSiteTap_">
+ hidden$="[[!showAddSiteButton_]]" on-click="onAddSiteTap_">
$i18n{add}
</cr-button>
</div>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.js b/chromium/chrome/browser/resources/settings/site_settings/site_list.js
index 5e9cbba9943..bdc541bd8a9 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_list.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.js
@@ -65,6 +65,16 @@ Polymer({
/** @private */
hasIncognito_: Boolean,
+ /**
+ * Whether to show the Add button next to the header.
+ * @private
+ */
+ showAddSiteButton_: {
+ type: Boolean,
+ computed: 'computeShowAddSiteButton_(readOnlyList, category, ' +
+ 'categorySubtype)',
+ },
+
/** @private */
showAddSiteDialog_: Boolean,
@@ -222,6 +232,20 @@ Polymer({
},
/**
+ * Whether the Add Site button is shown in the header for the current category
+ * and category subtype.
+ * @return {boolean}
+ * @private
+ */
+ computeShowAddSiteButton_: function() {
+ return !(
+ this.readOnlyList ||
+ (this.category ==
+ settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE &&
+ this.categorySubtype == settings.ContentSetting.ALLOW));
+ },
+
+ /**
* @return {boolean}
* @private
*/
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
index 9b3234d09ff..af45a352e33 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -193,8 +193,6 @@ const SiteSettingsBehaviorImpl = {
};
// These categories are gated behind flags.
addOrRemoveSettingWithFlag(
- settings.ContentSettingsTypes.SENSORS, 'enableSensorsContentSetting');
- addOrRemoveSettingWithFlag(
settings.ContentSettingsTypes.SERIAL_PORTS,
'enableExperimentalWebPlatformFeatures');
addOrRemoveSettingWithFlag(
@@ -206,6 +204,9 @@ const SiteSettingsBehaviorImpl = {
addOrRemoveSettingWithFlag(
settings.ContentSettingsTypes.BLUETOOTH_SCANNING,
'enableBluetoothScanningContentSetting');
+ addOrRemoveSettingWithFlag(
+ settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE,
+ 'enableNativeFileSystemWriteContentSetting');
return this.contentTypes_.slice(0);
},
diff --git a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
index f2b5e48bdc7..a2adc7f829b 100644
--- a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
+++ b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -66,15 +66,13 @@
'$i18nPolymer{siteSettingsAskBeforeAccessing}',
'$i18nPolymer{siteSettingsBlocked}')]]"></cr-link-row>
- <template is="dom-if" if="[[enableSensorsContentSetting_]]">
- <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_SENSORS"
- id="sensors" label="$i18n{siteSettingsSensors}"
- on-click="onTapNavigate_" start-icon="settings:sensors"
- sub-label="[[defaultSettingLabel_(
- default_.sensors,
- '$i18nPolymer{siteSettingsSensorsAllow}',
- '$i18nPolymer{siteSettingsSensorsBlock}')]]"></cr-link-row>
- </template>
+ <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_SENSORS"
+ id="sensors" label="$i18n{siteSettingsSensors}"
+ on-click="onTapNavigate_" start-icon="settings:sensors"
+ sub-label="[[defaultSettingLabel_(
+ default_.sensors,
+ '$i18nPolymer{siteSettingsSensorsAllow}',
+ '$i18nPolymer{siteSettingsSensorsBlock}')]]"></cr-link-row>
<cr-link-row class="hr two-line" data-route="SITE_SETTINGS_NOTIFICATIONS"
id="notifications" label="$i18n{siteSettingsNotifications}"
@@ -207,6 +205,19 @@
</cr-link-row>
</template>
+ <template is="dom-if" if="[[enableNativeFileSystemWriteContentSetting_]]">
+ <cr-link-row class="hr two-line"
+ data-route="SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE"
+ icon-class="subpage-arrow" id="native-file-system-write"
+ label="$i18n{siteSettingsNativeFileSystemWrite}"
+ on-click="onTapNavigate_" start-icon="settings:save-original"
+ sub-label="[[defaultSettingLabel_(
+ default_.filesystem,
+ '$i18nPolymer{siteSettingsNativeFileSystemWriteAsk}',
+ '$i18nPolymer{siteSettingsNativeFileSystemWriteBlock}')]]">
+ </cr-link-row>
+ </template>
+
<cr-link-row class="hr" data-route="SITE_SETTINGS_PDF_DOCUMENTS"
id="pdf-documents" label="$i18n{siteSettingsPdfDocuments}"
on-click="onTapNavigate_" start-icon="settings:pdf"></cr-link-row>
diff --git a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
index 85c0349ce7d..25bee399e1c 100644
--- a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
+++ b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -44,15 +44,6 @@ Polymer({
},
/** @private */
- enableSensorsContentSetting_: {
- type: Boolean,
- readOnly: true,
- value: function() {
- return loadTimeData.getBoolean('enableSensorsContentSetting');
- }
- },
-
- /** @private */
enableExperimentalWebPlatformFeatures_: {
type: Boolean,
value: function() {
@@ -76,6 +67,15 @@ Polymer({
}
},
+ /** @private */
+ enableNativeFileSystemWriteContentSetting_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean(
+ 'enableNativeFileSystemWriteContentSetting');
+ }
+ },
+
/** @type {!Map<string, (string|Function)>} */
focusConfig: {
type: Object,
@@ -134,6 +134,12 @@ Polymer({
pairs.push([R.SITE_SETTINGS_BLUETOOTH_SCANNING, 'bluetooth-scanning']);
}
+ if (this.enableNativeFileSystemWriteContentSetting_) {
+ pairs.push([
+ R.SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE, 'native-file-system-write'
+ ]);
+ }
+
pairs.forEach(([route, id]) => {
this.focusConfig.set(route.path, () => this.async(() => {
cr.ui.focusWithoutInk(assert(this.$$(`#${id}`)));
diff --git a/chromium/chrome/browser/resources/snippets_internals/snippets_internals.js b/chromium/chrome/browser/resources/snippets_internals/snippets_internals.js
index d3d057d16a6..99270fb3301 100644
--- a/chromium/chrome/browser/resources/snippets_internals/snippets_internals.js
+++ b/chromium/chrome/browser/resources/snippets_internals/snippets_internals.js
@@ -4,7 +4,7 @@
'use strict';
-/** @type {snippetsInternals.mojom.PageHandlerProxy} */
+/** @type {snippetsInternals.mojom.PageHandlerRemote} */
let pageHandler = null;
/** @type {snippetsInternals.mojom.PageInterface} */
@@ -245,6 +245,17 @@ function setupEventListeners() {
/* Represents the js-side of the IPC link. Backend talks to this. */
/** @implements {snippetsInternals.mojom.PageInterface} */
class SnippetsInternalsPageImpl {
+ constructor() {
+ this.receiver_ = new snippetsInternals.mojom.PageReceiver(this);
+ }
+
+ /**
+ * @return {!snippetsInternals.mojom.PageRemote}
+ */
+ bindNewPipeAndPassRemote() {
+ return this.receiver_.$.bindNewPipeAndPassRemote();
+ }
+
/* Callback for when suggestions change on the backend. */
onSuggestionsChanged() {
getSuggestionsByCategory();
@@ -254,25 +265,24 @@ class SnippetsInternalsPageImpl {
/* Main entry point. */
document.addEventListener('DOMContentLoaded', function() {
// Setup frontend mojo.
- page = new SnippetsInternalsPageImpl;
+ page = new SnippetsInternalsPageImpl();
// Setup backend mojo.
const pageHandlerFactory =
- snippetsInternals.mojom.PageHandlerFactory.getProxy();
+ snippetsInternals.mojom.PageHandlerFactory.getRemote();
// Give backend mojo a reference to frontend mojo.
- const client = new snippetsInternals.mojom.Page(page).$.createProxy();
- pageHandlerFactory.createPageHandler(client).then((response) => {
+ pageHandlerFactory.createPageHandler(page.bindNewPipeAndPassRemote())
+ .then((response) => {
+ pageHandler = response.handler;
- pageHandler = response.handler;
-
- // Populate value fields.
- refreshContent();
- getSuggestionsByCategory();
- setInterval(refreshContent, 2000);
+ // Populate value fields.
+ refreshContent();
+ getSuggestionsByCategory();
+ setInterval(refreshContent, 2000);
- // Setup events.
- setupEventListeners();
- });
+ // Setup events.
+ setupEventListeners();
+ });
});
}());
diff --git a/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp b/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp
new file mode 100644
index 00000000000..efdd213ea9f
--- /dev/null
+++ b/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <include name="IDR_SUPERVISED_USER_BLOCK_INTERSTITIAL_HTML" file="supervised_user/supervised_user_error_page/resources/supervised_user_block_interstitial.html" flattenhtml="true" type="BINDATA" />
+</grit-part>
diff --git a/chromium/chrome/browser/resources/tab_strip/BUILD.gn b/chromium/chrome/browser/resources/tab_strip/BUILD.gn
new file mode 100644
index 00000000000..ece86c1ad36
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/BUILD.gn
@@ -0,0 +1,61 @@
+# 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.
+
+import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
+
+js_type_check("closure_compile") {
+ deps = [
+ ":custom_element",
+ ":tab",
+ ":tab_list",
+ ":tabs_api_proxy",
+ ]
+}
+
+js_library("custom_element") {
+}
+
+js_library("tabs_api_proxy") {
+ deps = [
+ "//ui/webui/resources/js:cr.m",
+ ]
+ externs_list = [ "$externs_path/chrome_extensions.js" ]
+}
+
+js_library("tab") {
+ deps = [
+ "//ui/webui/resources/js:icon.m",
+ ]
+ externs_list = [ "$externs_path/chrome.js" ]
+}
+
+js_library("tab_list") {
+ deps = [
+ ":types",
+ ]
+ externs_list = [ "$externs_path/chrome.js" ]
+}
+
+js_library("types") {
+}
+
+group("tab_strip_modules") {
+ deps = [
+ ":tab_list_module",
+ ":tab_module",
+ ]
+}
+
+polymer_modulizer("tab") {
+ js_file = "tab.js"
+ html_file = "tab.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("tab_list") {
+ js_file = "tab_list.js"
+ html_file = "tab_list.html"
+ html_type = "v3-ready"
+}
diff --git a/chromium/chrome/browser/resources/tab_strip/OWNERS b/chromium/chrome/browser/resources/tab_strip/OWNERS
new file mode 100644
index 00000000000..c4454dd4ad5
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/OWNERS
@@ -0,0 +1,2 @@
+dpapad@chromium.org
+johntlee@chromium.org
diff --git a/chromium/chrome/browser/resources/tab_strip/custom_element.js b/chromium/chrome/browser/resources/tab_strip/custom_element.js
new file mode 100644
index 00000000000..2d8e4e91937
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/custom_element.js
@@ -0,0 +1,17 @@
+// 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.
+
+/**
+ * Super class for all custom elements defined in the tab strip.
+ */
+export class CustomElement extends HTMLElement {
+ constructor() {
+ super();
+
+ this.attachShadow({mode: 'open'});
+ const template = document.createElement('template');
+ template.innerHTML = this.constructor.template || '';
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
diff --git a/chromium/chrome/browser/resources/tab_strip/tab.html b/chromium/chrome/browser/resources/tab_strip/tab.html
new file mode 100644
index 00000000000..1e715432804
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab.html
@@ -0,0 +1,109 @@
+<style>
+ :host {
+ border-radius: var(--tabstrip-card-border-radius);
+ box-shadow: var(--tabstrip-elevation-box-shadow);
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ height: 230px;
+ overflow: hidden;
+ width: 280px;
+ }
+
+ :host([active]) {
+ box-shadow: 0 0 0 2px var(--tabstrip-focus-color);
+ outline: none;
+ }
+
+ #title {
+ align-items: center;
+ background: var(--tabstrip-card-background-color);
+ border-block-end: 1px solid var(--tabstrip-separator-color);
+ box-sizing: border-box;
+ display: flex;
+ height: 40px;
+ justify-content: center;
+ margin: 0;
+ padding-inline-end: 4px;
+ padding-inline-start: 12px;
+ }
+
+ #favicon {
+ flex-shrink: 0;
+ height: 16px;
+ margin-inline-end: 8px;
+ width: 16px;
+ }
+
+ #titleText {
+ font-size: 100%;
+ font-weight: normal;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ #close {
+ -webkit-appearance: none;
+ align-items: center;
+ background-color: transparent;
+ border: 0;
+ display: flex;
+ flex-shrink: 0;
+ height: 32px;
+ justify-content: center;
+ margin-inline-start: auto;
+ padding: 0;
+ position: relative;
+ width: 32px;
+ }
+
+ #closeIcon {
+ background:
+ url(chrome://resources/images/icon_clear.svg) center/contain no-repeat;
+ display: block;
+ height: 24px;
+ position: relative;
+ width: 24px;
+ }
+
+ #thumbnail {
+ background: var(--tabstrip-card-background-color);
+ flex: 1;
+ }
+
+ #thumbnailImg {
+ height: 100%;
+ object-fit: contain;
+ width: 100%;
+ }
+
+ /* Pinned tab styles */
+ :host([pinned]) {
+ height: 50px;
+ width: 50px;
+ }
+
+ :host([pinned]) #title {
+ border-block-end: 0;
+ height: 100%;
+ }
+
+ :host([pinned]) #titleText,
+ :host([pinned]) #close,
+ :host([pinned]) #thumbnail {
+ display: none;
+ }
+</style>
+
+<header id="title">
+ <span id="favicon"></span>
+ <h2 id="titleText"></h2>
+ <button id="close">
+ <span id="closeIcon"></span>
+ </button>
+</header>
+
+<div id="thumbnail">
+ <img id="thumbnailImg">
+</div>
diff --git a/chromium/chrome/browser/resources/tab_strip/tab.js b/chromium/chrome/browser/resources/tab_strip/tab.js
new file mode 100644
index 00000000000..0b16488f0ca
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab.js
@@ -0,0 +1,153 @@
+// 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.
+
+import {getFavicon, getFaviconForPageURL} from 'chrome://resources/js/icon.m.js';
+
+import {CustomElement} from './custom_element.js';
+import {TabsApiProxy} from './tabs_api_proxy.js';
+
+export const DEFAULT_ANIMATION_DURATION = 125;
+
+export class TabElement extends CustomElement {
+ static get template() {
+ return `{__html_template__}`;
+ }
+
+ constructor() {
+ super();
+
+ /** @private {!HTMLElement} */
+ this.closeButtonEl_ =
+ /** @type {!HTMLElement} */ (this.shadowRoot.querySelector('#close'));
+
+ /** @private {!HTMLElement} */
+ this.faviconEl_ =
+ /** @type {!HTMLElement} */ (this.shadowRoot.querySelector('#favicon'));
+
+ /** @private {!HTMLElement} */
+ this.thumbnailContainer_ =
+ /** @type {!HTMLElement} */ (
+ this.shadowRoot.querySelector('#thumbnail'));
+
+ /** @private {!Image} */
+ this.thumbnail_ =
+ /** @type {!Image} */ (this.shadowRoot.querySelector('#thumbnailImg'));
+
+ /** @private {!Tab} */
+ this.tab_;
+
+ /** @private {!TabsApiProxy} */
+ this.tabsApi_ = TabsApiProxy.getInstance();
+
+ /** @private {!HTMLElement} */
+ this.titleTextEl_ = /** @type {!HTMLElement} */ (
+ this.shadowRoot.querySelector('#titleText'));
+
+ this.addEventListener('click', this.onClick_.bind(this));
+ this.closeButtonEl_.addEventListener('click', this.onClose_.bind(this));
+ }
+
+ /** @return {!Tab} */
+ get tab() {
+ return this.tab_;
+ }
+
+ /** @param {!Tab} tab */
+ set tab(tab) {
+ this.toggleAttribute('active', tab.active);
+ this.toggleAttribute('pinned', tab.pinned);
+
+ if (!this.tab_ || this.tab_.title !== tab.title) {
+ this.titleTextEl_.textContent = tab.title;
+ }
+
+ if (tab.favIconUrl &&
+ (!this.tab_ || this.tab_.favIconUrl !== tab.favIconUrl)) {
+ this.faviconEl_.style.backgroundImage = getFavicon(tab.favIconUrl);
+ } else if (!this.tab_ || this.tab_.url !== tab.url) {
+ this.faviconEl_.style.backgroundImage =
+ getFaviconForPageURL(tab.url, false);
+ }
+
+ // Expose the ID to an attribute to allow easy querySelector use
+ this.setAttribute('data-tab-id', tab.id);
+
+ if (!this.tab_ || this.tab_.id !== tab.id) {
+ // Request thumbnail updates
+ chrome.send('addTrackedTab', [tab.id]);
+ }
+
+ this.tab_ = Object.freeze(tab);
+ }
+
+ /**
+ * @param {string} imgData
+ */
+ updateThumbnail(imgData) {
+ this.thumbnail_.src = imgData;
+ }
+
+ /** @private */
+ onClick_() {
+ if (!this.tab_) {
+ return;
+ }
+
+ this.tabsApi_.activateTab(this.tab_.id);
+ }
+
+ /**
+ * @param {!Event} event
+ * @private
+ */
+ onClose_(event) {
+ if (!this.tab_) {
+ return;
+ }
+
+ event.stopPropagation();
+ this.tabsApi_.closeTab(this.tab_.id);
+ }
+
+ /**
+ * @return {!Promise}
+ */
+ slideIn() {
+ return new Promise(resolve => {
+ const animation = this.animate(
+ [
+ {maxWidth: 0, opacity: 0},
+ {maxWidth: '280px', opacity: 1},
+ ],
+ {
+ duration: DEFAULT_ANIMATION_DURATION,
+ fill: 'forwards',
+ });
+ animation.onfinish = resolve;
+ });
+ }
+
+ /**
+ * @return {!Promise}
+ */
+ slideOut() {
+ return new Promise(resolve => {
+ const animation = this.animate(
+ [
+ {maxWidth: '280px', opacity: 1},
+ {maxWidth: 0, opacity: 0},
+ ],
+ {
+ duration: DEFAULT_ANIMATION_DURATION,
+ fill: 'forwards',
+ });
+ animation.onfinish = () => {
+ this.remove();
+ resolve();
+ };
+ });
+ }
+}
+
+customElements.define('tabstrip-tab', TabElement);
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.html b/chromium/chrome/browser/resources/tab_strip/tab_list.html
new file mode 100644
index 00000000000..680c562aa68
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.html
@@ -0,0 +1,51 @@
+<style>
+ :host {
+ display: flex;
+ padding: 16px;
+ width: fit-content;
+ }
+
+ #pinnedTabsContainer {
+ display: grid;
+ grid-auto-columns: 50px;
+ grid-auto-flow: column;
+ grid-gap: 10px;
+ grid-template-rows: repeat(4, 50px);
+ margin-inline-end: 16px;
+ }
+
+ #pinnedTabsContainer[empty] {
+ display: none;
+ }
+
+ .ghost-pinned-tab {
+ background: var(--tabstrip-card-background-color);
+ border-radius: var(--tabstrip-card-border-radius);
+ box-shadow: var(--tabstrip-elevation-box-shadow);
+ opacity: 0.5;
+ }
+
+ /* The #pinnedTabsContainer can only fit a maximum of 4 pinned tabs. The
+ * ghost-pinned-tab elements are meant to add as placeholders if there
+ * are not enough actual pinned tabs to fill an entire column. Therefore,
+ * all ghost-pinned-tabs after the 4 * nth element should be hidden. */
+ .ghost-pinned-tab:nth-child(4n + 1),
+ .ghost-pinned-tab:nth-child(4n + 1) ~ .ghost-pinned-tab {
+ display: none;
+ }
+
+ #tabsContainer {
+ display: flex;
+ }
+
+ #tabsContainer tabstrip-tab:not(:last-child) {
+ margin-inline-end: 16px;
+ }
+</style>
+
+<div id="pinnedTabsContainer" empty>
+ <div class="ghost-pinned-tab"></div>
+ <div class="ghost-pinned-tab"></div>
+ <div class="ghost-pinned-tab"></div>
+</div>
+<div id="tabsContainer"></div>
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.js b/chromium/chrome/browser/resources/tab_strip/tab_list.js
new file mode 100644
index 00000000000..dd72aec77bd
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.js
@@ -0,0 +1,249 @@
+// 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.
+
+import './tab.js';
+
+import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
+import {CustomElement} from './custom_element.js';
+import {TabElement} from './tab.js';
+import {TabsApiProxy} from './tabs_api_proxy.js';
+
+const GHOST_PINNED_TAB_COUNT = 3;
+
+class TabListElement extends CustomElement {
+ static get template() {
+ return `{__html_template__}`;
+ }
+
+ constructor() {
+ super();
+
+ /**
+ * A chain of promises that the tab list needs to keep track of. The chain
+ * is useful in cases when the list needs to wait for all animations to
+ * finish in order to get accurate pixels (such as getting the position of a
+ * tab) or accurate element counts.
+ * @type {!Promise}
+ */
+ this.animationPromises = Promise.resolve();
+
+ /** @private {!Element} */
+ this.pinnedTabsContainerElement_ =
+ /** @type {!Element} */ (
+ this.shadowRoot.querySelector('#pinnedTabsContainer'));
+
+ /** @private {!TabsApiProxy} */
+ this.tabsApi_ = TabsApiProxy.getInstance();
+
+ /** @private {!Object} */
+ this.tabsApiHandler_ = this.tabsApi_.callbackRouter;
+
+ /** @private {!Element} */
+ this.tabsContainerElement_ =
+ /** @type {!Element} */ (
+ this.shadowRoot.querySelector('#tabsContainer'));
+
+ /** @private {number} */
+ this.windowId_;
+
+ addWebUIListener(
+ 'tab-thumbnail-updated', this.tabThumbnailUpdated_.bind(this));
+ }
+
+ /**
+ * @param {!Promise} promise
+ * @private
+ */
+ addAnimationPromise_(promise) {
+ this.animationPromises = this.animationPromises.then(() => promise);
+ }
+
+ connectedCallback() {
+ this.tabsApi_.getCurrentWindow().then((currentWindow) => {
+ this.windowId_ = currentWindow.id;
+
+ // TODO(johntlee): currentWindow.tabs is guaranteed to be defined because
+ // `populate: true` is passed in as part of the arguments to the API.
+ // Once the closure compiler is able to type `assert` to return a truthy
+ // type even when being used with modules, the conditionals should be
+ // replaced with `assert` (b/138729777).
+ if (currentWindow.tabs) {
+ for (const tab of currentWindow.tabs) {
+ if (tab) {
+ this.onTabCreated_(tab);
+ }
+ }
+ }
+
+ this.tabsApiHandler_.onActivated.addListener(
+ this.onTabActivated_.bind(this));
+ this.tabsApiHandler_.onCreated.addListener(this.onTabCreated_.bind(this));
+ this.tabsApiHandler_.onMoved.addListener(this.onTabMoved_.bind(this));
+ this.tabsApiHandler_.onRemoved.addListener(this.onTabRemoved_.bind(this));
+ this.tabsApiHandler_.onUpdated.addListener(this.onTabUpdated_.bind(this));
+ });
+ }
+
+ /**
+ * @param {!Tab} tab
+ * @return {!TabElement}
+ * @private
+ */
+ createTabElement_(tab) {
+ const tabElement = new TabElement();
+ tabElement.tab = tab;
+ return tabElement;
+ }
+
+ /**
+ * @param {number} tabId
+ * @return {?TabElement}
+ * @private
+ */
+ findTabElement_(tabId) {
+ return /** @type {?TabElement} */ (
+ this.shadowRoot.querySelector(`tabstrip-tab[data-tab-id="${tabId}"]`));
+ }
+
+ /**
+ * @param {!TabElement} tabElement
+ * @param {number} index
+ * @private
+ */
+ insertTabOrMoveTo_(tabElement, index) {
+ // Remove the tabElement if it already exists in the DOM
+ tabElement.remove();
+
+ if (tabElement.tab && tabElement.tab.pinned) {
+ this.pinnedTabsContainerElement_.insertBefore(
+ tabElement, this.pinnedTabsContainerElement_.childNodes[index]);
+ } else {
+ // Pinned tabs are in their own container, so the index of non-pinned
+ // tabs need to be offset by the number of pinned tabs
+ const offsetIndex = index -
+ (this.pinnedTabsContainerElement_.childElementCount -
+ GHOST_PINNED_TAB_COUNT);
+ this.tabsContainerElement_.insertBefore(
+ tabElement, this.tabsContainerElement_.childNodes[offsetIndex]);
+ }
+
+ this.updatePinnedTabsState_();
+ }
+
+ /**
+ * @param {!TabActivatedInfo} activeInfo
+ * @private
+ */
+ onTabActivated_(activeInfo) {
+ if (activeInfo.windowId !== this.windowId_) {
+ return;
+ }
+
+ const previouslyActiveTab =
+ this.shadowRoot.querySelector('tabstrip-tab[active]');
+ if (previouslyActiveTab) {
+ previouslyActiveTab.tab = /** @type {!Tab} */ (
+ Object.assign({}, previouslyActiveTab.tab, {active: false}));
+ }
+
+ const newlyActiveTab = this.findTabElement_(activeInfo.tabId);
+ newlyActiveTab.tab = /** @type {!Tab} */ (
+ Object.assign({}, newlyActiveTab.tab, {active: true}));
+ }
+
+ /**
+ * @param {!Tab} tab
+ * @private
+ */
+ onTabCreated_(tab) {
+ if (tab.windowId !== this.windowId_) {
+ return;
+ }
+
+ const tabElement = this.createTabElement_(tab);
+ this.insertTabOrMoveTo_(tabElement, tab.index);
+ this.addAnimationPromise_(tabElement.slideIn());
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {!TabMovedInfo} moveInfo
+ * @private
+ */
+ onTabMoved_(tabId, moveInfo) {
+ if (moveInfo.windowId !== this.windowId_) {
+ return;
+ }
+
+ const movedTab = this.findTabElement_(tabId);
+ if (movedTab) {
+ this.insertTabOrMoveTo_(movedTab, moveInfo.toIndex);
+ }
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {!WindowRemoveInfo} removeInfo
+ * @private
+ */
+ onTabRemoved_(tabId, removeInfo) {
+ if (removeInfo.windowId !== this.windowId_) {
+ return;
+ }
+
+ const tabElement = this.findTabElement_(tabId);
+ if (tabElement) {
+ this.addAnimationPromise_(new Promise(async resolve => {
+ await tabElement.slideOut();
+ this.updatePinnedTabsState_();
+ resolve();
+ }));
+ }
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {!Tab} changeInfo
+ * @param {!Tab} tab
+ * @private
+ */
+ onTabUpdated_(tabId, changeInfo, tab) {
+ if (tab.windowId !== this.windowId_) {
+ return;
+ }
+
+ const tabElement = this.findTabElement_(tabId);
+ if (tabElement) {
+ tabElement.tab = tab;
+
+ if (changeInfo.pinned !== undefined) {
+ // If the tab is being pinned or unpinned, we need to move it to its new
+ // location
+ this.insertTabOrMoveTo_(tabElement, tab.index);
+ }
+ }
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {string} imgData
+ * @private
+ */
+ tabThumbnailUpdated_(tabId, imgData) {
+ const tab = this.findTabElement_(tabId);
+ if (tab) {
+ tab.updateThumbnail(imgData);
+ }
+ }
+
+ /** @private */
+ updatePinnedTabsState_() {
+ this.pinnedTabsContainerElement_.toggleAttribute(
+ 'empty',
+ this.pinnedTabsContainerElement_.childElementCount ===
+ GHOST_PINNED_TAB_COUNT);
+ }
+}
+
+customElements.define('tabstrip-tab-list', TabListElement);
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip.html b/chromium/chrome/browser/resources/tab_strip/tab_strip.html
new file mode 100644
index 00000000000..088f0ea0097
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
+ <head>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
+ <style>
+ html {
+ --google-grey-50-rgb: 248, 249, 250;
+ --google-grey-200-rgb: 232, 234, 237;
+ --google-grey-300-rgb: 218, 220, 224;
+ --google-grey-800-rgb: 60, 64, 67;
+ --google-grey-900-rgb: 32, 33, 36;
+ --google-blue-300-rgb: 138, 180, 248;
+ --google-blue-500-rgb: 66, 133, 244;
+
+ --tabstrip-background-color: rgb(var(--google-grey-50-rgb));
+ --tabstrip-card-background-color: white;
+ --tabstrip-card-border-radius: 8px;
+ --tabstrip-elevation-box-shadow:
+ 0 0 0 1px rgb(var(--google-grey-300-rgb));
+ --tabstrip-focus-color: rgb(var(--google-blue-500-rgb));
+ --tabstrip-primary-text-color: rgb(var(--google-grey-900-rgb));
+ --tabstrip-separator-color: rgb(var(--google-grey-300-rgb));
+ }
+
+ @media (prefers-color-scheme: dark) {
+ html {
+ --tabstrip-background-color: rgba(var(--google-grey-900-rgb));
+ --tabstrip-card-background-color: rgba(255, 255, 255, 0.04);
+ --tabstrip-elevation-box-shadow: none;
+ --tabstrip-focus-color: rgb(var(--google-blue-300-rgb));
+ --tabstrip-primary-text-color: rgb(var(--google-grey-200-rgb));
+ --tabstrip-separator-color: rgb(255, 255, 255, 0.1);
+ }
+ }
+
+ body {
+ background: var(--tabstrip-background-color);
+ color: var(--tabstrip-primary-text-color);
+ margin: 0;
+ padding: 0;
+ }
+
+ ::-webkit-scrollbar {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <tabstrip-tab-list></tabstrip-tab-list>
+ <script src="tab_list.js" type="module"></script>
+ </body>
+</html>
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
new file mode 100644
index 00000000000..72257fd7930
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+ <outputs>
+ <output filename="grit/tab_strip_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="grit/tab_strip_resources_map.cc"
+ type="resource_file_map_source" />
+ <output filename="grit/tab_strip_resources_map.h"
+ type="resource_map_header" />
+ <output filename="tab_strip_resources.pak" type="data_package" />
+ </outputs>
+ <release seq="1">
+ <structures>
+ <structure
+ name="IDR_TAB_STRIP_HTML"
+ file="tab_strip.html"
+ type="chrome_html"
+ compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_TABS_API_PROXY_JS"
+ file="tabs_api_proxy.js"
+ type="chrome_html"
+ compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_CUSTOM_ELEMENT_JS"
+ file="custom_element.js"
+ type="chrome_html"
+ compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_TAB_LIST_JS"
+ file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab_list.js"
+ use_base_dir="false"
+ type="chrome_html"
+ compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_TAB_JS"
+ file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab.js"
+ use_base_dir="false"
+ type="chrome_html"
+ compress="gzip"/>
+ </structures>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js b/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
new file mode 100644
index 00000000000..9ce6ad61f28
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
@@ -0,0 +1,68 @@
+// 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.
+
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+
+export class TabsApiProxy {
+ constructor() {
+ /** @type {!Object<string, !ChromeEvent>} */
+ this.callbackRouter = {
+ onActivated: chrome.tabs.onActivated,
+ onCreated: chrome.tabs.onCreated,
+ onMoved: chrome.tabs.onMoved,
+ onRemoved: chrome.tabs.onRemoved,
+ onUpdated: chrome.tabs.onUpdated,
+ };
+ }
+
+ /**
+ * @param {number} tabId
+ * @return {!Promise<!Tab>}
+ */
+ activateTab(tabId) {
+ return new Promise(resolve => {
+ chrome.tabs.update(tabId, {active: true}, resolve);
+ });
+ }
+
+ /**
+ * @return {!Promise<!ChromeWindow>}
+ */
+ getCurrentWindow() {
+ const options = {
+ populate: true, // populate window data with tabs data
+ windowTypes: ['normal'], // prevent devtools from being returned
+ };
+ return new Promise(resolve => {
+ chrome.windows.getCurrent(options, currentWindow => {
+ resolve(currentWindow);
+ });
+ });
+ }
+
+ /**
+ * @param {number} tabId
+ * @return {!Promise}
+ */
+ closeTab(tabId) {
+ return new Promise(resolve => {
+ chrome.tabs.remove(tabId, resolve);
+ });
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {number} newIndex
+ * @return {!Promise<!Tab>}
+ */
+ moveTab(tabId, newIndex) {
+ return new Promise(resolve => {
+ chrome.tabs.move(tabId, {index: newIndex}, tab => {
+ resolve(tab);
+ });
+ });
+ }
+}
+
+addSingletonGetter(TabsApiProxy);
diff --git a/chromium/chrome/browser/resources/tab_strip/types.js b/chromium/chrome/browser/resources/tab_strip/types.js
new file mode 100644
index 00000000000..6496711a0da
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/types.js
@@ -0,0 +1,32 @@
+// 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 Closure typedefs for Tab Strip.
+ */
+
+/**
+ * @typedef {{
+ * tabId: number,
+ * windowId: number,
+ * }}
+ */
+let TabActivatedInfo;
+
+/**
+ * @typedef {{
+ * fromIndex: number,
+ * toIndex: number,
+ * windowId: number,
+ * }}
+ */
+let TabMovedInfo;
+
+/**
+ * @typedef {{
+ * isWindowClosing: boolean,
+ * windowId: number,
+ * }}
+ */
+let WindowRemoveInfo;
diff --git a/chromium/chrome/browser/resources/usb_internals/BUILD.gn b/chromium/chrome/browser/resources/usb_internals/BUILD.gn
index 28ec89bb179..d4d21445df1 100644
--- a/chromium/chrome/browser/resources/usb_internals/BUILD.gn
+++ b/chromium/chrome/browser/resources/usb_internals/BUILD.gn
@@ -7,26 +7,33 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":descriptor_panel",
- ":device_page",
+ ":devices_page",
":usb_internals",
]
}
js_library("usb_internals") {
deps = [
- ":device_page",
+ ":devices_page",
"//chrome/browser/ui/webui/usb_internals:mojo_bindings_js_library_for_compile",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:util",
"//ui/webui/resources/js/cr/ui:tabs",
+ "//ui/webui/resources/js/cr/ui:tree",
]
}
js_library("devices_page") {
deps = [
":descriptor_panel",
+ "//chrome/browser/ui/webui/usb_internals:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr",
]
}
js_library("descriptor_panel") {
+ deps = [
+ "//chrome/browser/ui/webui/usb_internals:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr",
+ ]
}
diff --git a/chromium/chrome/browser/resources/usb_internals/descriptor_panel.js b/chromium/chrome/browser/resources/usb_internals/descriptor_panel.js
index 62d2910203f..6c0bfa8271c 100644
--- a/chromium/chrome/browser/resources/usb_internals/descriptor_panel.js
+++ b/chromium/chrome/browser/resources/usb_internals/descriptor_panel.js
@@ -125,10 +125,10 @@ cr.define('descriptor_panel', function() {
/**
* Adds the reference of the string descriptor panel of the device for
* string descriptor functionality.
- * @param {!DescriptorPanel} stringDescriptorPanel
+ * @param {!descriptor_panel.DescriptorPanel} stringDescriptorPanel
*/
setStringDescriptorPanel(stringDescriptorPanel) {
- /** @type {!DescriptorPanel} */
+ /** @type {!descriptor_panel.DescriptorPanel} */
this.stringDescriptorPanel_ = stringDescriptorPanel;
}
@@ -166,7 +166,7 @@ cr.define('descriptor_panel', function() {
this.stringDescriptorPanel_.stringDescriptorIndexes.add(index);
}
- const buttonTemplate = document.querySelector('#raw-data-tree-button');
+ const buttonTemplate = queryRequiredElement('#raw-data-tree-button');
const button = document.importNode(buttonTemplate.content, true)
.querySelector('button');
item.labelElement.appendChild(button);
@@ -200,7 +200,7 @@ cr.define('descriptor_panel', function() {
renderUrlDescriptorIndexItem_(rawData, offset, item, fieldLabel) {
const index = rawData[offset];
if (index > 0) {
- const buttonTemplate = document.querySelector('#raw-data-tree-button');
+ const buttonTemplate = queryRequiredElement('#raw-data-tree-button');
const button = document.importNode(buttonTemplate.content, true)
.querySelector('button');
item.labelElement.appendChild(button);
@@ -238,7 +238,7 @@ cr.define('descriptor_panel', function() {
const msOs20DescriptorSetLength =
data.getUint16(MS_OS_20_SET_TOTAL_LENGTH_OFFSET, true);
- const buttonTemplate = document.querySelector('#raw-data-tree-button');
+ const buttonTemplate = queryRequiredElement('#raw-data-tree-button');
const button = document.importNode(buttonTemplate.content, true)
.querySelector('button');
item.labelElement.appendChild(button);
@@ -277,7 +277,7 @@ cr.define('descriptor_panel', function() {
if (altEnumCode !== 0) {
const vendorCode = rawData[offset + MS_OS_20_VENDOR_CODE_ITEM_OFFSET];
- const buttonTemplate = document.querySelector('#raw-data-tree-button');
+ const buttonTemplate = queryRequiredElement('#raw-data-tree-button');
const button = document.importNode(buttonTemplate.content, true)
.querySelector('button');
item.labelElement.appendChild(button);
@@ -451,14 +451,13 @@ cr.define('descriptor_panel', function() {
*/
async getDeviceDescriptor() {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.STANDARD;
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- usbControlTransferParams.request = GET_DESCRIPTOR_REQUEST;
- usbControlTransferParams.value = (DEVICE_DESCRIPTOR_TYPE << 8);
- usbControlTransferParams.index = 0;
+ const usbControlTransferParams = {
+ type: device.mojom.UsbControlTransferType.STANDARD,
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ request: GET_DESCRIPTOR_REQUEST,
+ value: DEVICE_DESCRIPTOR_TYPE << 8,
+ index: 0,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -577,14 +576,13 @@ cr.define('descriptor_panel', function() {
*/
async getConfigurationDescriptor() {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.STANDARD;
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- usbControlTransferParams.request = GET_DESCRIPTOR_REQUEST;
- usbControlTransferParams.value = (CONFIGURATION_DESCRIPTOR_TYPE << 8);
- usbControlTransferParams.index = 0;
+ const usbControlTransferParams = {
+ type: device.mojom.UsbControlTransferType.STANDARD,
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ request: GET_DESCRIPTOR_REQUEST,
+ value: CONFIGURATION_DESCRIPTOR_TYPE << 8,
+ index: 0,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -683,7 +681,7 @@ cr.define('descriptor_panel', function() {
* @param {number} offset The start offset of the interface
* descriptor.
* @param {number} indexInterface
- * @return {!Array<number>}
+ * @return {!cr.ui.TreeItem}
* @private
*/
renderInterfaceDescriptor_(
@@ -752,13 +750,12 @@ cr.define('descriptor_panel', function() {
/**
* Renders a tree item to display endpoint descriptor at index
* indexEndpoint.
- * @param {!cr.ui.Tree} rawDataTreeRoot
+ * @param {!cr.ui.Tree|!cr.ui.TreeItem} rawDataTreeRoot
* @param {!HTMLElement} rawDataByteElement
* @param {!Uint8Array} rawData
* @param {number} offset The start offset of the endpoint
* descriptor.
* @param {number} indexEndpoint
- * @return {number}
* @private
*/
renderEndpointDescriptor_(
@@ -814,7 +811,6 @@ cr.define('descriptor_panel', function() {
* @param {!Uint8Array} rawData
* @param {number} originalOffset The start offset of the this descriptor.
* @param {number} indexUnknown
- * @return {number}
* @private
*/
renderUnknownDescriptor_(
@@ -856,18 +852,17 @@ cr.define('descriptor_panel', function() {
* Gets all the supported language codes of this device, and adds them as
* autocompletions for the language code input area in the string descriptor
* panel.
- * @return {!Array<string>}
+ * @return {!Promise<!Array<number>>}
*/
async getAllLanguageCodes() {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.STANDARD;
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- usbControlTransferParams.request = GET_DESCRIPTOR_REQUEST;
- usbControlTransferParams.value = (STRING_DESCRIPTOR_TYPE << 8);
- usbControlTransferParams.index = 0;
+ const usbControlTransferParams = {
+ type: device.mojom.UsbControlTransferType.STANDARD,
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ request: GET_DESCRIPTOR_REQUEST,
+ value: STRING_DESCRIPTOR_TYPE << 8,
+ index: 0,
+ };
let response;
try {
@@ -886,7 +881,7 @@ cr.define('descriptor_panel', function() {
showError(e.message, this.rootElement_);
// Stop rendering autocomplete datalist if failed to read the string
// descriptor.
- return new Uint8Array();
+ return [];
} finally {
await this.usbDeviceProxy_.close();
}
@@ -920,20 +915,18 @@ cr.define('descriptor_panel', function() {
* @param {number} index
* @param {number} languageCode
* @param {!cr.ui.TreeItem=} treeItem
- * @return {{languageCode:string,rawData:!Uint8Array}}
* @private
*/
async getStringDescriptorForLanguageCode_(
index, languageCode, treeItem = undefined) {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.STANDARD;
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- usbControlTransferParams.request = GET_DESCRIPTOR_REQUEST;
- usbControlTransferParams.index = languageCode;
- usbControlTransferParams.value = (STRING_DESCRIPTOR_TYPE << 8) | index;
+ const usbControlTransferParams = {
+ type: device.mojom.UsbControlTransferType.STANDARD,
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ request: GET_DESCRIPTOR_REQUEST,
+ index: languageCode,
+ value: (STRING_DESCRIPTOR_TYPE << 8) | index,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -1025,18 +1018,18 @@ cr.define('descriptor_panel', function() {
this.indexInput_.value = index;
- /** @type {!Array<number>|undefined} */
+ /** @type {!Array<number>} */
const languageCodesList = await this.getAllLanguageCodes();
for (const languageCode of languageCodesList) {
await this.getStringDescriptorForLanguageCode_(
- index, languageCode, treeItem);
+ index, languageCode, assert(treeItem));
}
}
/**
* Initializes the string descriptor panel for autocomplete functionality.
- * @param {number} tabId
+ * @param {string} tabId
*/
initialStringDescriptorPanel(tabId) {
// Binds the input area and datalist use each tab's unique id.
@@ -1046,21 +1039,22 @@ cr.define('descriptor_panel', function() {
.forEach(el => el.id = `${el.id}-${tabId}`);
/** @type {!HTMLElement} */
- const button = this.rootElement_.querySelector('button');
+ const button = queryRequiredElement('button', this.rootElement_);
/** @type {!HTMLElement} */
- this.indexInput_ = this.rootElement_.querySelector('#index-input');
+ this.indexInput_ =
+ queryRequiredElement('#index-input', this.rootElement_);
/** @type {!HTMLElement} */
const languageCodeInput =
- this.rootElement_.querySelector('#language-code-input');
+ queryRequiredElement('#language-code-input', this.rootElement_);
button.addEventListener('click', async () => {
this.clearView();
- const index = Number.parseInt(this.indexInput_.value);
+ const index = Number.parseInt(this.indexInput_.value, 10);
if (this.checkParamValid_(index, 'Index', 1, 255)) {
if (languageCodeInput.value === 'All') {
await this.getStringDescriptorForAllLanguages_(index);
} else {
- const languageCode = Number.parseInt(languageCodeInput.value);
+ const languageCode = Number.parseInt(languageCodeInput.value, 10);
if (this.checkParamValid_(
languageCode, 'Language Code', 0, 65535)) {
await this.getStringDescriptorForLanguageCode_(
@@ -1074,10 +1068,10 @@ cr.define('descriptor_panel', function() {
this.stringDescriptorIndexes = new Set();
/** @type {!HTMLElement} */
this.indexesListElement =
- this.rootElement_.querySelector(`#indexes-${tabId}`);
+ queryRequiredElement(`#indexes-${tabId}`, this.rootElement_);
/** @type {!HTMLElement} */
this.languageCodesListElement_ =
- this.rootElement_.querySelector(`#languages-${tabId}`);
+ queryRequiredElement(`#languages-${tabId}`, this.rootElement_);
}
/**
@@ -1087,14 +1081,13 @@ cr.define('descriptor_panel', function() {
*/
async getBosDescriptor() {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.STANDARD;
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- usbControlTransferParams.request = GET_DESCRIPTOR_REQUEST;
- usbControlTransferParams.value = (BOS_DESCRIPTOR_TYPE << 8);
- usbControlTransferParams.index = 0;
+ const usbControlTransferParams = {
+ type: device.mojom.UsbControlTransferType.STANDARD,
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ request: GET_DESCRIPTOR_REQUEST,
+ value: BOS_DESCRIPTOR_TYPE << 8,
+ index: 0,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -1183,13 +1176,13 @@ cr.define('descriptor_panel', function() {
break;
} else if (isSameUuid(
rawData, offset, MS_OS_20_PLATFORM_CAPABILITY_UUID)) {
- offset = this.renderMsOs20PlatformDescriptor_(
+ this.renderMsOs20PlatformDescriptor_(
rawDataTreeRoot, rawDataByteElement, rawData, offset,
indexDevCapability);
break;
}
default:
- offset = this.renderUnknownBosDescriptor_(
+ this.renderUnknownBosDescriptor_(
rawDataTreeRoot, rawDataByteElement, rawData, offset,
indexDevCapability);
}
@@ -1326,7 +1319,7 @@ cr.define('descriptor_panel', function() {
/**
* Renders a tree item to display Microsoft OS 2.0 descriptor set
* information at index indexMsOs20DescriptorSetInfo.
- * @param {!cr.ui.Tree} rawDataTreeRoot
+ * @param {!cr.ui.Tree|!cr.ui.TreeItem} rawDataTreeRoot
* @param {!HTMLElement} rawDataByteElement
* @param {!Uint8Array} rawData
* @param {number} offset The start offset of the Microsoft OS 2.0
@@ -1451,16 +1444,15 @@ cr.define('descriptor_panel', function() {
const urlIndex = rawData[offset + WEB_USB_URL_DESCRIPTOR_INDEX_OFFSET];
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- // These constants are defined by the WebUSB specification:
- // http://wicg.github.io/webusb/
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.VENDOR;
- usbControlTransferParams.request = vendorCode;
- usbControlTransferParams.value = urlIndex;
- usbControlTransferParams.index = GET_URL_REQUEST;
+ const usbControlTransferParams = {
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ // These constants are defined by the WebUSB specification:
+ // http://wicg.github.io/webusb/
+ type: device.mojom.UsbControlTransferType.VENDOR,
+ request: vendorCode,
+ value: urlIndex,
+ index: GET_URL_REQUEST,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -1509,21 +1501,20 @@ cr.define('descriptor_panel', function() {
/**
* Gets the Microsoft OS 2.0 Descriptor vendor-specific descriptor.
* @param {number} vendorCode
- * @return {!Uint8Array}
+ * @return {!Promise<!Uint8Array>}
* @private
*/
async getMsOs20DescriptorSet_(vendorCode, msOs20DescriptorSetLength) {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- // These constants are defined by Microsoft OS 2.0 Descriptors
- // Specification (July, 2018).
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.VENDOR;
- usbControlTransferParams.request = vendorCode;
- usbControlTransferParams.value = 0;
- usbControlTransferParams.index = MS_OS_20_DESCRIPTOR_INDEX;
+ const usbControlTransferParams = {
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ // These constants are defined by Microsoft OS 2.0 Descriptors
+ // Specification (July, 2018).
+ type: device.mojom.UsbControlTransferType.VENDOR,
+ request: vendorCode,
+ value: 0,
+ index: MS_OS_20_DESCRIPTOR_INDEX,
+ };
let response;
try {
@@ -1541,7 +1532,7 @@ cr.define('descriptor_panel', function() {
showError(e.message, this.rootElement_);
// Returns an empty array if failed to read the Microsoft OS 2.0
// descriptor set.
- return new Uint8Array();
+ return new Uint8Array(0);
} finally {
await this.usbDeviceProxy_.close();
}
@@ -1557,16 +1548,15 @@ cr.define('descriptor_panel', function() {
*/
async sendMsOs20DescriptorSetAltEnumCommand_(vendorCode, altEnumCode) {
/** @type {!device.mojom.UsbControlTransferParams} */
- const usbControlTransferParams = {};
- usbControlTransferParams.recipient =
- device.mojom.UsbControlTransferRecipient.DEVICE;
- // These constants are defined by Microsoft OS 2.0 Descriptors
- // Specification (July, 2018).
- usbControlTransferParams.type =
- device.mojom.UsbControlTransferType.VENDOR;
- usbControlTransferParams.request = vendorCode;
- usbControlTransferParams.value = altEnumCode;
- usbControlTransferParams.index = MS_OS_20_SET_ALT_ENUMERATION;
+ const usbControlTransferParams = {
+ recipient: device.mojom.UsbControlTransferRecipient.DEVICE,
+ // These constants are defined by Microsoft OS 2.0 Descriptors
+ // Specification (July, 2018).
+ type: device.mojom.UsbControlTransferType.VENDOR,
+ request: vendorCode,
+ value: altEnumCode,
+ index: MS_OS_20_SET_ALT_ENUMERATION,
+ };
try {
await this.usbDeviceProxy_.open();
@@ -2311,7 +2301,7 @@ cr.define('descriptor_panel', function() {
* Gets response of the given request.
* @param {!device.mojom.UsbControlTransferParams} usbControlTransferParams
* @param {number} length
- * @param {number} direction
+ * @param {string} direction
* @private
*/
async sendTestingRequest_(usbControlTransferParams, length, direction) {
@@ -2333,8 +2323,7 @@ cr.define('descriptor_panel', function() {
}
const response = await this.usbDeviceProxy_.controlTransferOut(
- usbControlTransferParams, new Uint8Array(data),
- CONTROL_TRANSFER_TIMEOUT_MS);
+ usbControlTransferParams, data, CONTROL_TRANSFER_TIMEOUT_MS);
checkTransferSuccess(
response.status, 'Failed to send request.', this.rootElement_);
}
@@ -2387,17 +2376,20 @@ cr.define('descriptor_panel', function() {
this.clearView();
const index = testingToolPanelInputTypeSelector.selectedIndex;
inputTableRows.forEach(row => row.hidden = true);
- inputTableRows[index].hidden = false;
+ const rowAtIndex = assertInstanceof(inputTableRows[index], HTMLElement);
+ rowAtIndex.hidden = false;
- const direction = getRequestTypeDirection(inputTableRows[index], index);
- const length = getRequestLength(inputTableRows[index], index);
+ const direction = getRequestTypeDirection(rowAtIndex, index);
+ const length = getRequestLength(rowAtIndex, index);
this.rootElement_.querySelector('#data-input-area').hidden =
(direction !== 'Host-to-Device');
dataInputArea.value = '00'.repeat(length);
dataInputArea.maxLength = length * 2;
});
- for (const [i, inputTableRow] of inputTableRows.entries()) {
+
+ inputTableRows.forEach((el, i) => {
+ const inputTableRow = assertInstanceof(el, HTMLElement);
let directionInputElement;
switch (i) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
@@ -2420,19 +2412,20 @@ cr.define('descriptor_panel', function() {
dataInputArea.value = '00'.repeat(length);
dataInputArea.maxLength = length * 2;
});
- }
+ });
- for (const [i, button] of buttons.entries()) {
+ buttons.forEach((button, i) => {
button.addEventListener('click', () => {
this.clearView();
- const direction = getRequestTypeDirection(inputTableRows[i], i);
- const type = getRequestType(inputTableRows[i], i);
- const recipient = getRequestTypeRecipient(inputTableRows[i], i);
- const request = getRequestCode(inputTableRows[i], i);
- const value = getRequestValue(inputTableRows[i], i);
- const index = getRequestIndex(inputTableRows[i], i);
- const dataLength = getRequestLength(inputTableRows[i], i);
+ const row = assertInstanceof(inputTableRows[i], HTMLElement);
+ const direction = getRequestTypeDirection(row, i);
+ const type = getRequestType(row, i);
+ const recipient = getRequestTypeRecipient(row, i);
+ const request = getRequestCode(row, i);
+ const value = getRequestValue(row, i);
+ const index = getRequestIndex(row, i);
+ const dataLength = getRequestLength(row, i);
if (this.checkEnumParamValid_(
type, 'Transfer Type', device.mojom.UsbControlTransferType) &&
@@ -2455,7 +2448,7 @@ cr.define('descriptor_panel', function() {
usbControlTransferParams, dataLength, direction);
}
});
- }
+ });
}
/**
@@ -2501,10 +2494,10 @@ cr.define('descriptor_panel', function() {
function getRequestType(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return inputRow.querySelector('#transfer-type').value;
+ return queryRequiredElement('#transfer-type', inputRow).value;
case INPUT_TYPE_HEX_BYTE:
const value = Number.parseInt(
- inputRow.querySelector('#query-request-type').value, 16);
+ queryRequiredElement('#query-request-type', inputRow).value, 16);
switch (value >> 5 & 0x03) {
case 0:
return 'STANDARD';
@@ -2527,10 +2520,10 @@ cr.define('descriptor_panel', function() {
function getRequestTypeRecipient(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return inputRow.querySelector('#transfer-recipient').value;
+ return queryRequiredElement('#transfer-recipient', inputRow).value;
case INPUT_TYPE_HEX_BYTE:
const value = Number.parseInt(
- inputRow.querySelector('#query-request-type').value, 16);
+ queryRequiredElement('#query-request-type', inputRow).value, 16);
switch (value & 0x1F) {
case 0:
return 'DEVICE';
@@ -2551,15 +2544,15 @@ cr.define('descriptor_panel', function() {
* host-to-device.
* @param {!HTMLElement} inputRow
* @param {number} inputType
- * @return {number}
+ * @return {string}
*/
function getRequestTypeDirection(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return inputRow.querySelector('#transfer-direction').value;
+ return queryRequiredElement('#transfer-direction', inputRow).value;
case INPUT_TYPE_HEX_BYTE:
const value = Number.parseInt(
- inputRow.querySelector('#query-request-type').value, 16);
+ queryRequiredElement('#query-request-type', inputRow).value, 16);
switch (value >> 7) {
case CONTROL_TRANSFER_DIRECTION_HOST_TO_DEVICE:
return 'Host-to-Device';
@@ -2580,10 +2573,11 @@ cr.define('descriptor_panel', function() {
function getRequestCode(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return Number.parseInt(inputRow.querySelector('#query-request').value);
+ return Number.parseInt(
+ queryRequiredElement('#query-request', inputRow).value, 10);
case INPUT_TYPE_HEX_BYTE:
return Number.parseInt(
- inputRow.querySelector('#query-request').value, 16);
+ queryRequiredElement('#query-request', inputRow).value, 16);
default:
return Number.NaN;
}
@@ -2598,10 +2592,11 @@ cr.define('descriptor_panel', function() {
function getRequestValue(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return Number.parseInt(inputRow.querySelector('#query-value').value);
+ return Number.parseInt(
+ queryRequiredElement('#query-value', inputRow).value, 10);
case INPUT_TYPE_HEX_BYTE:
return Number.parseInt(
- inputRow.querySelector('#query-value').value, 16);
+ queryRequiredElement('#query-value', inputRow).value, 16);
default:
return Number.NaN;
}
@@ -2616,10 +2611,11 @@ cr.define('descriptor_panel', function() {
function getRequestIndex(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return Number.parseInt(inputRow.querySelector('#query-index').value);
+ return Number.parseInt(
+ queryRequiredElement('#query-index', inputRow).value, 10);
case INPUT_TYPE_HEX_BYTE:
return Number.parseInt(
- inputRow.querySelector('#query-index').value, 16);
+ queryRequiredElement('#query-index', inputRow).value, 16);
default:
return Number.NaN;
}
@@ -2634,10 +2630,11 @@ cr.define('descriptor_panel', function() {
function getRequestLength(inputRow, inputType) {
switch (inputType) {
case INPUT_TYPE_DECIMAL_WITH_DROPDOWN:
- return Number.parseInt(inputRow.querySelector('#query-length').value);
+ return Number.parseInt(
+ queryRequiredElement('#query-length', inputRow).value, 10);
case INPUT_TYPE_HEX_BYTE:
return Number.parseInt(
- inputRow.querySelector('#query-length').value, 16);
+ queryRequiredElement('#query-length', inputRow).value, 16);
default:
return Number.NaN;
}
@@ -2652,23 +2649,24 @@ cr.define('descriptor_panel', function() {
function addNewDescriptorDisplayElement(
rootElement, descriptorPanelTitle = undefined) {
const descriptorPanelTemplate =
- document.querySelector('#descriptor-panel-template');
- const descriptorPanelClone =
- document.importNode(descriptorPanelTemplate.content, true);
+ queryRequiredElement('#descriptor-panel-template');
+
+ const descriptorPanelClone = /** @type {!HTMLElement} */
+ (document.importNode(descriptorPanelTemplate.content, true));
/** @type {!HTMLElement} */
const rawDataTreeRoot =
- descriptorPanelClone.querySelector('.raw-data-tree-view');
+ queryRequiredElement('.raw-data-tree-view', descriptorPanelClone);
/** @type {!HTMLElement} */
const rawDataByteElement =
- descriptorPanelClone.querySelector('.raw-data-byte-view');
+ queryRequiredElement('.raw-data-byte-view', descriptorPanelClone);
cr.ui.decorate(rawDataTreeRoot, cr.ui.Tree);
rawDataTreeRoot.detail = {payload: {}, children: {}};
if (descriptorPanelTitle) {
const descriptorPanelTitleTemplate =
- document.querySelector('#descriptor-panel-title');
+ queryRequiredElement('#descriptor-panel-title');
const clone =
document.importNode(descriptorPanelTitleTemplate.content, true)
.querySelector('descriptorpaneltitle');
@@ -2774,7 +2772,8 @@ cr.define('descriptor_panel', function() {
el.addEventListener('pointerenter', () => {
rawDataByteElement.querySelectorAll(`.${fieldOffsetClass}`)
.forEach((el) => el.classList.add('hovered-field'));
- const el = rawDataTreeRoot.querySelector(`.${fieldOffsetClass}`);
+ const el =
+ queryRequiredElement(`.${fieldOffsetClass}`, rawDataTreeRoot);
if (el) {
el.classList.add('hover');
}
@@ -2783,14 +2782,16 @@ cr.define('descriptor_panel', function() {
el.addEventListener('pointerleave', () => {
rawDataByteElement.querySelectorAll(`.${fieldOffsetClass}`)
.forEach((el) => el.classList.remove('hovered-field'));
- const el = rawDataTreeRoot.querySelector(`.${fieldOffsetClass}`);
+ const el =
+ queryRequiredElement(`.${fieldOffsetClass}`, rawDataTreeRoot);
if (el) {
el.classList.remove('hover');
}
});
el.addEventListener('click', () => {
- const el = rawDataTreeRoot.querySelector(`.${fieldOffsetClass}`);
+ const el =
+ queryRequiredElement(`.${fieldOffsetClass}`, rawDataTreeRoot);
if (el) {
el.click();
}
@@ -2857,19 +2858,17 @@ cr.define('descriptor_panel', function() {
*/
function renderRawDataBytes(rawDataByteElement, rawData) {
const rawDataByteContainerTemplate =
- document.querySelector('#raw-data-byte-container-template');
+ queryRequiredElement('#raw-data-byte-container-template');
const rawDataByteContainerClone =
document.importNode(rawDataByteContainerTemplate.content, true);
const rawDataByteContainerElement =
rawDataByteContainerClone.querySelector('div');
- const rawDataByteTemplate =
- document.querySelector('#raw-data-byte-template');
+ const rawDataByteTemplate = queryRequiredElement('#raw-data-byte-template');
for (const value of rawData) {
const rawDataByteClone =
document.importNode(rawDataByteTemplate.content, true);
const rawDataByteElement = rawDataByteClone.querySelector('span');
-
rawDataByteElement.textContent = toHex(value, 2);
rawDataByteContainerElement.appendChild(rawDataByteElement);
}
diff --git a/chromium/chrome/browser/resources/usb_internals/devices_page.js b/chromium/chrome/browser/resources/usb_internals/devices_page.js
index e7743ac9062..2589e5eb286 100644
--- a/chromium/chrome/browser/resources/usb_internals/devices_page.js
+++ b/chromium/chrome/browser/resources/usb_internals/devices_page.js
@@ -8,17 +8,17 @@
*/
cr.define('devices_page', function() {
- const UsbDeviceProxy = device.mojom.UsbDeviceProxy;
+ const UsbDeviceRemote = device.mojom.UsbDeviceRemote;
/**
* Page that contains a tab header and a tab panel displaying devices table.
*/
class DevicesPage {
/**
- * @param {!device.mojom.UsbDeviceManagerProxy} usbManager
+ * @param {!device.mojom.UsbDeviceManagerRemote} usbManager
*/
constructor(usbManager) {
- /** @private {device.mojom.UsbDeviceManagerProxy} */
+ /** @private {!device.mojom.UsbDeviceManagerRemote} */
this.usbManager_ = usbManager;
this.renderDeviceList_();
}
@@ -28,7 +28,7 @@ cr.define('devices_page', function() {
* @private
*/
async renderDeviceList_() {
- const response = await this.usbManager_.getDevices();
+ const response = await this.usbManager_.getDevices(null);
/** @type {!Array<!device.mojom.UsbDeviceInfo>} */
const devices = response.results;
@@ -39,6 +39,7 @@ cr.define('devices_page', function() {
const rowTemplate = document.querySelector('#device-row');
for (const device of devices) {
+ /** @type {DocumentFragment|Node} */
const clone = document.importNode(rowTemplate.content, true);
const td = clone.querySelectorAll('td');
@@ -48,13 +49,13 @@ cr.define('devices_page', function() {
td[2].textContent = toHex(device.vendorId);
td[3].textContent = toHex(device.productId);
if (device.manufacturerName) {
- td[4].textContent = decodeString16(device.manufacturerName.data);
+ td[4].textContent = decodeString16(device.manufacturerName);
}
if (device.productName) {
- td[5].textContent = decodeString16(device.productName.data);
+ td[5].textContent = decodeString16(device.productName);
}
if (device.serialNumber) {
- td[6].textContent = decodeString16(device.serialNumber.data);
+ td[6].textContent = decodeString16(device.serialNumber);
}
const inspectButton = clone.querySelector('button');
@@ -90,11 +91,10 @@ cr.define('devices_page', function() {
*/
class DevicePage {
/**
- * @param {!device.mojom.UsbDeviceManagerProxy} usbManager
+ * @param {!device.mojom.UsbDeviceManagerRemote} usbManager
* @param {!device.mojom.UsbDeviceInfo} device
*/
constructor(usbManager, device) {
- /** @private {device.mojom.UsbDeviceManagerProxy} */
this.usbManager_ = usbManager;
this.renderTab_(device);
}
@@ -105,14 +105,15 @@ cr.define('devices_page', function() {
* @private
*/
renderTab_(device) {
- const tabs = document.querySelector('tabs');
+ const tabs = queryRequiredElement('tabs');
- const tabTemplate = document.querySelector('#tab-template');
+ const tabTemplate = queryRequiredElement('#tab-template');
+ /** @type {DocumentFragment|Node} */
const tabClone = document.importNode(tabTemplate.content, true);
const tab = tabClone.querySelector('tab');
if (device.productName) {
- tab.textContent = decodeString16(device.productName.data);
+ tab.textContent = decodeString16(device.productName);
} else {
const vendorId = toHex(device.vendorId).slice(2);
const productId = toHex(device.productId).slice(2);
@@ -123,23 +124,25 @@ cr.define('devices_page', function() {
tabs.appendChild(tabClone);
cr.ui.decorate('tab', cr.ui.Tab);
- const tabPanels = document.querySelector('tabpanels');
+ const tabPanels = queryRequiredElement('tabpanels');
const tabPanelTemplate =
- document.querySelector('#device-tabpanel-template');
+ queryRequiredElement('#device-tabpanel-template');
+ /** @type {DocumentFragment|Node} */
const tabPanelClone = document.importNode(tabPanelTemplate.content, true);
/**
* Root of the WebContents tree of current device.
- * @type {?cr.ui.Tree}
*/
- const treeViewRoot = tabPanelClone.querySelector('.tree-view');
+ const treeViewRoot = assertInstanceof(
+ tabPanelClone.querySelector('.tree-view'), HTMLElement);
cr.ui.decorate(treeViewRoot, cr.ui.Tree);
treeViewRoot.detail = {payload: {}, children: {}};
// Clear the tree first before populating it with the new content.
treeViewRoot.innerText = '';
renderDeviceTree(device, treeViewRoot);
- const tabPanel = tabPanelClone.querySelector('tabpanel');
+ const tabPanel = assertInstanceof(
+ tabPanelClone.querySelector('tabpanel'), HTMLElement);
this.initializeDescriptorPanels_(tabPanel, device.guid);
tabPanels.appendChild(tabPanelClone);
@@ -153,24 +156,25 @@ cr.define('devices_page', function() {
* @private
*/
async initializeDescriptorPanels_(tabPanel, guid) {
- const usbDeviceProxy = new UsbDeviceProxy;
- await this.usbManager_.getDevice(guid, usbDeviceProxy.$.createRequest());
+ const usbDevice = new UsbDeviceRemote;
+ await this.usbManager_.getDevice(
+ guid, usbDevice.$.bindNewPipeAndPassReceiver(), null);
- const deviceDescriptorPanel = initialInspectorPanel(
- tabPanel, 'device-descriptor', usbDeviceProxy, guid);
+ const deviceDescriptorPanel =
+ initialInspectorPanel(tabPanel, 'device-descriptor', usbDevice, guid);
const configurationDescriptorPanel = initialInspectorPanel(
- tabPanel, 'configuration-descriptor', usbDeviceProxy, guid);
+ tabPanel, 'configuration-descriptor', usbDevice, guid);
- const stringDescriptorPanel = initialInspectorPanel(
- tabPanel, 'string-descriptor', usbDeviceProxy, guid);
+ const stringDescriptorPanel =
+ initialInspectorPanel(tabPanel, 'string-descriptor', usbDevice, guid);
deviceDescriptorPanel.setStringDescriptorPanel(stringDescriptorPanel);
configurationDescriptorPanel.setStringDescriptorPanel(
stringDescriptorPanel);
- initialInspectorPanel(tabPanel, 'bos-descriptor', usbDeviceProxy, guid);
+ initialInspectorPanel(tabPanel, 'bos-descriptor', usbDevice, guid);
- initialInspectorPanel(tabPanel, 'testing-tool', usbDeviceProxy, guid);
+ initialInspectorPanel(tabPanel, 'testing-tool', usbDevice, guid);
// window.deviceTabInitializedFn() provides a hook for the test suite to
// perform test actions after the device tab query descriptors actions are
@@ -204,18 +208,18 @@ cr.define('devices_page', function() {
device.deviceVersionMinor}.${device.deviceVersionSubminor}`));
if (device.manufacturerName) {
- root.add(customTreeItem(`Manufacturer Name: ${
- decodeString16(device.manufacturerName.data)}`));
+ root.add(customTreeItem(
+ `Manufacturer Name: ${decodeString16(device.manufacturerName)}`));
}
if (device.productName) {
root.add(customTreeItem(
- `Product Name: ${decodeString16(device.productName.data)}`));
+ `Product Name: ${decodeString16(device.productName)}`));
}
if (device.serialNumber) {
root.add(customTreeItem(
- `Serial Number: ${decodeString16(device.serialNumber.data)}`));
+ `Serial Number: ${decodeString16(device.serialNumber)}`));
}
if (device.webusbLandingPage) {
@@ -239,7 +243,7 @@ cr.define('devices_page', function() {
/**
* Renders a tree item to display the device's configuration information.
* @param {!Array<!device.mojom.UsbConfigurationInfo>} configurationsArray
- * @param {!cr.ui.TreeItem} root
+ * @param {!cr.ui.Tree} root
*/
function renderConfigurationTreeItem(configurationsArray, root) {
for (const configuration of configurationsArray) {
@@ -248,7 +252,7 @@ cr.define('devices_page', function() {
if (configuration.configurationName) {
configurationItem.add(customTreeItem(`Configuration Name: ${
- decodeString16(configuration.configurationName.data)}`));
+ decodeString16(configuration.configurationName)}`));
}
const interfacesArray = configuration.interfaces;
@@ -296,7 +300,7 @@ cr.define('devices_page', function() {
if (alternate.interfaceName) {
alternateItem.add(customTreeItem(
- `Interface Name: ${decodeString16(alternate.interfaceName.data)}`));
+ `Interface Name: ${decodeString16(alternate.interfaceName)}`));
}
const endpointsArray = alternate.endpoints;
@@ -356,15 +360,16 @@ cr.define('devices_page', function() {
* Initialize a descriptor panel.
* @param {!HTMLElement} tabPanel
* @param {string} panelType
- * @param {!device.mojom.UsbDeviceInterface} usbDeviceProxy
+ * @param {!device.mojom.UsbDeviceRemote} usbDevice
* @param {string} guid
* @return {!descriptor_panel.DescriptorPanel}
*/
- function initialInspectorPanel(tabPanel, panelType, usbDeviceProxy, guid) {
- const button = tabPanel.querySelector(`.${panelType}-button`);
- const displayElement = tabPanel.querySelector(`.${panelType}-panel`);
+ function initialInspectorPanel(tabPanel, panelType, usbDevice, guid) {
+ const button = queryRequiredElement(`.${panelType}-button`, tabPanel);
+ const displayElement =
+ queryRequiredElement(`.${panelType}-panel`, tabPanel);
const descriptorPanel =
- new descriptor_panel.DescriptorPanel(usbDeviceProxy, displayElement);
+ new descriptor_panel.DescriptorPanel(usbDevice, displayElement);
switch (panelType) {
case 'string-descriptor':
descriptorPanel.initialStringDescriptorPanel(guid);
@@ -405,7 +410,7 @@ cr.define('devices_page', function() {
* @return {string}
*/
function decodeString16(arr) {
- return arr.map(ch => String.fromCodePoint(ch)).join('');
+ return arr.data.map(ch => String.fromCodePoint(ch)).join('');
}
/**
@@ -424,7 +429,7 @@ cr.define('devices_page', function() {
* @private
*/
function customTreeItem(itemLabel) {
- return item = new cr.ui.TreeItem({
+ return new cr.ui.TreeItem({
label: itemLabel,
icon: '',
});
@@ -437,4 +442,4 @@ cr.define('devices_page', function() {
window.deviceListCompleteFn = window.deviceListCompleteFn || function() {};
-window.deviceTabInitializedFn = window.deviceTabInitializedFn || function() {}; \ No newline at end of file
+window.deviceTabInitializedFn = window.deviceTabInitializedFn || function() {};
diff --git a/chromium/chrome/browser/resources/usb_internals/usb_internals.js b/chromium/chrome/browser/resources/usb_internals/usb_internals.js
index ff0683482ef..45bce591f47 100644
--- a/chromium/chrome/browser/resources/usb_internals/usb_internals.js
+++ b/chromium/chrome/browser/resources/usb_internals/usb_internals.js
@@ -14,20 +14,20 @@ cr.define('usb_internals', function() {
// actions after the page is loaded but before any script is run.
await window.setupFn();
- const pageHandler = mojom.UsbInternalsPageHandler.getProxy();
+ const pageHandler = mojom.UsbInternalsPageHandler.getRemote();
// Connection to the UsbInternalsPageHandler instance running in the
// browser process.
- /** @type {device.mojom.UsbDeviceManagerProxy} */
- const usbManager = new device.mojom.UsbDeviceManagerProxy;
+ /** @type {device.mojom.UsbDeviceManagerRemote} */
+ const usbManager = new device.mojom.UsbDeviceManagerRemote;
await pageHandler.bindUsbDeviceManagerInterface(
usbManager.$.createRequest());
/** @private {devices_page.DevicesPage} */
this.devicesPage_ = new devices_page.DevicesPage(usbManager);
- /** @private {device.mojom.UsbDeviceManagerTestProxy} */
- this.usbManagerTest_ = new device.mojom.UsbDeviceManagerTestProxy;
+ /** @private {device.mojom.UsbDeviceManagerTestRemote} */
+ this.usbManagerTest_ = new device.mojom.UsbDeviceManagerTestRemote;
await pageHandler.bindTestInterface(
this.usbManagerTest_.$.createRequest());
@@ -93,4 +93,4 @@ window.setupFn = window.setupFn || function() {
document.addEventListener('DOMContentLoaded', () => {
const usbInternalsPage = new usb_internals.UsbInternals();
usbInternalsPage.initializeViews();
-}); \ No newline at end of file
+});
diff --git a/chromium/chrome/browser/resources/web_footer_experiment/index.html b/chromium/chrome/browser/resources/web_footer_experiment/index.html
new file mode 100644
index 00000000000..ea952773de5
--- /dev/null
+++ b/chromium/chrome/browser/resources/web_footer_experiment/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <style>
+ body {
+ background-color: #9e9e9e;
+ }
+ </style>
+</head>
+</html>
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 a5d31e14e95..fd03465f37a 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
@@ -143,38 +143,38 @@
/* App Icons */
.gmail {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_GMAIL@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_GMAIL@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_GMAIL@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_GMAIL@2x) 2x);
}
.youtube {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_YOUTUBE@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_YOUTUBE@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_YOUTUBE@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_YOUTUBE@2x) 2x);
}
.maps {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_MAPS@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_MAPS@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_MAPS@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_MAPS@2x) 2x);
}
.translate {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_TRANSLATE@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_TRANSLATE@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_TRANSLATE@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_TRANSLATE@2x) 2x);
}
.news {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_NEWS@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_NEWS@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_NEWS@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_NEWS@2x) 2x);
}
.search {
content: -webkit-image-set(
- url(chrome://theme/IDS_ONBOARDING_WELCOME_SEARCH@1x) 1x,
- url(chrome://theme/IDS_ONBOARDING_WELCOME_SEARCH@2x) 2x);
+ url(chrome://theme/IDS_WELCOME_SEARCH@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_SEARCH@2x) 2x);
}
</style>
<div class="apps-ask">
diff --git a/chromium/chrome/browser/resources/welcome/onboarding_welcome_resources.grd b/chromium/chrome/browser/resources/welcome/welcome_resources.grd
index 011b9b184a4..cc67d33b906 100644
--- a/chromium/chrome/browser/resources/welcome/onboarding_welcome_resources.grd
+++ b/chromium/chrome/browser/resources/welcome/welcome_resources.grd
@@ -1,199 +1,199 @@
<?xml version="1.0" encoding="UTF-8"?>
<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
<outputs>
- <output filename="grit/onboarding_welcome_resources.h"
+ <output filename="grit/welcome_resources.h"
type="rc_header">
<emit emit_type='prepend'></emit>
</output>
- <output filename="grit/onboarding_welcome_resources_map.cc"
+ <output filename="grit/welcome_resources_map.cc"
type="resource_file_map_source" />
- <output filename="grit/onboarding_welcome_resources_map.h"
+ <output filename="grit/welcome_resources_map.h"
type="resource_map_header" />
- <output filename="onboarding_welcome_resources.pak"
+ <output filename="welcome_resources.pak"
type="data_package" />
</outputs>
<release seq="1">
<includes>
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_BLUE_CIRCLE_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_BLUE_CIRCLE_SVG"
file="images/background_svgs/blue_circle.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREEN_RECTANGLE_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_GREEN_RECTANGLE_SVG"
file="images/background_svgs/green_rectangle.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_OVAL_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_OVAL_SVG"
file="images/background_svgs/grey_oval.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_ROUNDED_RECTANGLE_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_ROUNDED_RECTANGLE_SVG"
file="images/background_svgs/grey_rounded_rectangle.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_RED_TRIANGLE_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_RED_TRIANGLE_SVG"
file="images/background_svgs/red_triangle.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_DOTS_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_DOTS_SVG"
file="images/background_svgs/yellow_dots.svg"
compress="gzip"
type="BINDATA" />
- <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_SEMICIRCLE_SVG"
+ <include name="IDR_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_SEMICIRCLE_SVG"
file="images/background_svgs/yellow_semicircle.svg"
compress="gzip"
type="BINDATA" />
</includes>
<structures>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_LANDING_VIEW_HTML"
+ <structure name="IDR_WELCOME_LANDING_VIEW_HTML"
file="landing_view.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_LANDING_VIEW_JS"
+ <structure name="IDR_WELCOME_LANDING_VIEW_JS"
file="landing_view.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_LANDING_VIEW_PROXY_HTML"
+ <structure name="IDR_WELCOME_LANDING_VIEW_PROXY_HTML"
file="landing_view_proxy.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_LANDING_VIEW_PROXY_JS"
+ <structure name="IDR_WELCOME_LANDING_VIEW_PROXY_JS"
file="landing_view_proxy.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_NAVIGATION_BEHAVIOR_HTML"
+ <structure name="IDR_WELCOME_NAVIGATION_BEHAVIOR_HTML"
file="navigation_behavior.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_NAVIGATION_BEHAVIOR_JS"
+ <structure name="IDR_WELCOME_NAVIGATION_BEHAVIOR_JS"
file="navigation_behavior.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_JS"
+ <structure name="IDR_WELCOME_SHARED_ACTION_LINK_STYLE_JS"
file="shared/action_link_style.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_CSS_HTML"
+ <structure name="IDR_WELCOME_SHARED_ACTION_LINK_STYLE_CSS_HTML"
file="shared/action_link_style_css.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ANIMATIONS_CSS"
+ <structure name="IDR_WELCOME_SHARED_ANIMATIONS_CSS"
file="shared/animations_css.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_BOOKMARK_PROXY_HTML"
+ <structure name="IDR_WELCOME_SHARED_BOOKMARK_PROXY_HTML"
file="shared/bookmark_proxy.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_BOOKMARK_PROXY_JS"
+ <structure name="IDR_WELCOME_SHARED_BOOKMARK_PROXY_JS"
file="shared/bookmark_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_CHOOSER_SHARED_CSS"
+ <structure name="IDR_WELCOME_SHARED_CHOOSER_SHARED_CSS"
file="shared/chooser_shared_css.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_I18N_SETUP_HTML"
+ <structure name="IDR_WELCOME_SHARED_I18N_SETUP_HTML"
file="shared/i18n_setup.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_MODULE_METRICS_PROXY_HTML"
+ <structure name="IDR_WELCOME_SHARED_MODULE_METRICS_PROXY_HTML"
file="shared/module_metrics_proxy.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_MODULE_METRICS_PROXY_JS"
+ <structure name="IDR_WELCOME_SHARED_MODULE_METRICS_PROXY_JS"
file="shared/module_metrics_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_NAVI_COLORS_CSS"
+ <structure name="IDR_WELCOME_SHARED_NAVI_COLORS_CSS"
file="shared/navi_colors_css.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_HTML"
+ <structure name="IDR_WELCOME_SHARED_ONBOARDING_BACKGROUND_HTML"
file="shared/onboarding_background.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS"
+ <structure name="IDR_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS"
file="shared/onboarding_background.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_STEP_INDICATOR_HTML"
+ <structure name="IDR_WELCOME_SHARED_STEP_INDICATOR_HTML"
file="shared/step_indicator.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_STEP_INDICATOR_JS"
+ <structure name="IDR_WELCOME_SHARED_STEP_INDICATOR_JS"
file="shared/step_indicator.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_SPLASH_PAGES_SHARED_CSS"
+ <structure name="IDR_WELCOME_SHARED_SPLASH_PAGES_SHARED_CSS"
file="shared/splash_pages_shared_css.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_HTML"
+ <structure name="IDR_WELCOME_SIGNIN_VIEW_HTML"
file="signin_view.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_JS"
+ <structure name="IDR_WELCOME_SIGNIN_VIEW_JS"
file="signin_view.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_PROXY_HTML"
+ <structure name="IDR_WELCOME_SIGNIN_VIEW_PROXY_HTML"
file="signin_view_proxy.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_PROXY_JS"
+ <structure name="IDR_WELCOME_SIGNIN_VIEW_PROXY_JS"
file="signin_view_proxy.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_APP_HTML"
+ <structure name="IDR_WELCOME_APP_HTML"
file="welcome_app.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_APP_JS"
+ <structure name="IDR_WELCOME_APP_JS"
file="welcome_app.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_BROWSER_PROXY_HTML"
+ <structure name="IDR_WELCOME_BROWSER_PROXY_HTML"
file="welcome_browser_proxy.html"
compress="gzip"
type="chrome_html"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_BROWSER_PROXY_JS"
+ <structure name="IDR_WELCOME_BROWSER_PROXY_JS"
file="welcome_browser_proxy.js"
compress="gzip"
type="chrome_html"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_CSS"
+ <structure name="IDR_WELCOME_CSS"
file="welcome.css"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_HTML"
+ <structure name="IDR_WELCOME_HTML"
file="welcome.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_JS"
+ <structure name="IDR_WELCOME_JS"
file="welcome.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <!-- NUX Google apps-->
- <structure name="IDR_NUX_GOOGLE_APPS_HTML"
+ <!-- Google apps-->
+ <structure name="IDR_GOOGLE_APPS_HTML"
file="google_apps/nux_google_apps.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_GOOGLE_APPS_JS"
+ <structure name="IDR_GOOGLE_APPS_JS"
file="google_apps/nux_google_apps.js"
compress="gzip"
type="chrome_html" />
@@ -205,21 +205,21 @@
file="google_apps/google_app_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_SET_AS_DEFAULT_HTML"
+ <structure name="IDR_SET_AS_DEFAULT_HTML"
file="set_as_default/nux_set_as_default.html"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_NUX_SET_AS_DEFAULT_JS"
+ <structure name="IDR_SET_AS_DEFAULT_JS"
file="set_as_default/nux_set_as_default.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_NUX_SET_AS_DEFAULT_PROXY_HTML"
+ <structure name="IDR_SET_AS_DEFAULT_PROXY_HTML"
file="set_as_default/nux_set_as_default_proxy.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_SET_AS_DEFAULT_PROXY_JS"
+ <structure name="IDR_SET_AS_DEFAULT_PROXY_JS"
file="set_as_default/nux_set_as_default_proxy.js"
compress="gzip"
type="chrome_html" />
@@ -232,28 +232,28 @@
compress="gzip"
type="chrome_html" />
- <!-- NUX NTP background-->
- <structure name="IDR_NUX_NTP_BACKGROUND_HTML"
+ <!-- NTP background-->
+ <structure name="IDR_NTP_BACKGROUND_HTML"
file="ntp_background/nux_ntp_background.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_NTP_BACKGROUND_JS"
+ <structure name="IDR_NTP_BACKGROUND_JS"
file="ntp_background/nux_ntp_background.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_NTP_BACKGROUND_PROXY_HTML"
+ <structure name="IDR_NTP_BACKGROUND_PROXY_HTML"
file="ntp_background/ntp_background_proxy.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_NTP_BACKGROUND_PROXY_JS"
+ <structure name="IDR_NTP_BACKGROUND_PROXY_JS"
file="ntp_background/ntp_background_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_NTP_BACKGROUND_METRICS_PROXY_HTML"
+ <structure name="IDR_NTP_BACKGROUND_METRICS_PROXY_HTML"
file="ntp_background/ntp_background_metrics_proxy.html"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_NUX_NTP_BACKGROUND_METRICS_PROXY_JS"
+ <structure name="IDR_NTP_BACKGROUND_METRICS_PROXY_JS"
file="ntp_background/ntp_background_metrics_proxy.js"
compress="gzip"
type="chrome_html" />