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.gn79
-rw-r--r--chromium/chrome/browser/resources/accessibility/accessibility.html94
-rw-r--r--chromium/chrome/browser/resources/accessibility/accessibility.js74
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn24
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js7
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html13
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js8
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/debug_log_page.js68
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/page.html1
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/page.js314
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/page_manager.html1
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/page_manager.js800
-rw-r--r--chromium/chrome/browser/resources/bluetooth_internals/resources.grd21
-rw-r--r--chromium/chrome/browser/resources/bookmarks/README.md6
-rw-r--r--chromium/chrome/browser/resources/bookmarks/command_manager.html2
-rw-r--r--chromium/chrome/browser/resources/bookmarks/command_manager.js28
-rw-r--r--chromium/chrome/browser/resources/bookmarks/shared_style.html4
-rw-r--r--chromium/chrome/browser/resources/browser_switch/BUILD.gn15
-rw-r--r--chromium/chrome/browser/resources/browser_switch/app.html68
-rw-r--r--chromium/chrome/browser/resources/browser_switch/app.js14
-rw-r--r--chromium/chrome/browser/resources/browser_switch/browser_switch.html5
-rw-r--r--chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.js49
-rw-r--r--chromium/chrome/browser/resources/chromeos/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/BUILD.gn23
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd19
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json30
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn22
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/device/BUILD.gn5
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/externs/BUILD.gn (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/BUILD.gn)9
-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.gn9
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/js/views/camera/BUILD.gn (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/BUILD.gn)16
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/manifest.json9
-rw-r--r--chromium/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd21
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json32
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd43
-rw-r--r--chromium/chrome/browser/resources/chromeos/crostini_installer/BUILD.gn44
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json5
-rw-r--r--chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json5
-rw-r--r--chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/chromeos/login/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/chromeos/network_ui/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn26
-rw-r--r--chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn13
-rw-r--r--chromium/chrome/browser/resources/component_extension_resources.grd52
-rw-r--r--chromium/chrome/browser/resources/conflicts/about_conflicts.html26
-rw-r--r--chromium/chrome/browser/resources/conflicts/about_conflicts.js20
-rw-r--r--chromium/chrome/browser/resources/cryptotoken/enroller.js53
-rw-r--r--chromium/chrome/browser/resources/dev_ui/dev_ui_loader_error.html (renamed from chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css)29
-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/discards/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/discards/database_tab.js60
-rw-r--r--chromium/chrome/browser/resources/discards/discards.js4
-rw-r--r--chromium/chrome/browser/resources/discards/discards_tab.js48
-rw-r--r--chromium/chrome/browser/resources/discards/graph_doc.js28
-rw-r--r--chromium/chrome/browser/resources/discards/graph_tab.js20
-rw-r--r--chromium/chrome/browser/resources/discards/mojo_api.html1
-rw-r--r--chromium/chrome/browser/resources/download_internals/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/download_internals/download_internals.html8
-rw-r--r--chromium/chrome/browser/resources/downloads/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/downloads/item.html2
-rw-r--r--chromium/chrome/browser/resources/extensions/BUILD.gn93
-rw-r--r--chromium/chrome/browser/resources/extensions/detail_view.html40
-rw-r--r--chromium/chrome/browser/resources/extensions/extensions.html2
-rw-r--r--chromium/chrome/browser/resources/extensions/extensions_resources.grd6
-rw-r--r--chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.html1
-rw-r--r--chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.js41
-rw-r--r--chromium/chrome/browser/resources/extensions/keyboard_shortcuts.html1
-rw-r--r--chromium/chrome/browser/resources/extensions/keyboard_shortcuts.js31
-rw-r--r--chromium/chrome/browser/resources/extensions/toolbar.html9
-rw-r--r--chromium/chrome/browser/resources/extensions/toolbar.js18
-rw-r--r--chromium/chrome/browser/resources/feedback/html/default.html5
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/authenticator.js12
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js58
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js159
-rw-r--r--chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator_test.unitjs76
-rw-r--r--chromium/chrome/browser/resources/hangout_services/OWNERS2
-rw-r--r--chromium/chrome/browser/resources/hats/hats.html7
-rw-r--r--chromium/chrome/browser/resources/history/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/history/history_list.html1
-rw-r--r--chromium/chrome/browser/resources/history/history_list.js7
-rw-r--r--chromium/chrome/browser/resources/identity_internals/identity_internals.js2
-rw-r--r--chromium/chrome/browser/resources/inline_login/inline_login.html1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/customize.css26
-rw-r--r--chromium/chrome/browser/resources/local_ntp/customize.js121
-rw-r--r--chromium/chrome/browser/resources/local_ntp/doodles.css30
-rw-r--r--chromium/chrome/browser/resources/local_ntp/externs.js70
-rw-r--r--chromium/chrome/browser/resources/local_ntp/icons/clock.svg1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/icons/close.svg1
-rw-r--r--chromium/chrome/browser/resources/local_ntp/icons/dont_show.pngbin0 -> 101 bytes
-rw-r--r--chromium/chrome/browser/resources/local_ntp/icons/dont_show_2x.pngbin0 -> 133 bytes
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.css315
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.html22
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp.js903
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp_common.css2
-rw-r--r--chromium/chrome/browser/resources/local_ntp/local_ntp_resources.grd2
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.css71
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.html2
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.js274
-rw-r--r--chromium/chrome/browser/resources/management/BUILD.gn31
-rw-r--r--chromium/chrome/browser/resources/management/icons.html5
-rw-r--r--chromium/chrome/browser/resources/management/icons.js10
-rw-r--r--chromium/chrome/browser/resources/management/management.html4
-rw-r--r--chromium/chrome/browser/resources/management/management_browser_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/management/management_browser_proxy.js278
-rw-r--r--chromium/chrome/browser/resources/management/management_ui.html19
-rw-r--r--chromium/chrome/browser/resources/management/management_ui.js539
-rw-r--r--chromium/chrome/browser/resources/media_router/BUILD.gn (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn)9
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router_internals.html4
-rw-r--r--chromium/chrome/browser/resources/media_router/media_router_internals.js28
-rw-r--r--chromium/chrome/browser/resources/ntp4/apps_page.js4
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css2
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_tab.css46
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_tab.html11
-rw-r--r--chromium/chrome/browser/resources/ntp4/incognito_tab.js26
-rw-r--r--chromium/chrome/browser/resources/ntp4/nav_dot.js2
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_tab.css11
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_tab.html2
-rw-r--r--chromium/chrome/browser/resources/ntp4/new_tab.js14
-rw-r--r--chromium/chrome/browser/resources/ntp4/tile_page.js4
-rw-r--r--chromium/chrome/browser/resources/offline_pages/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/offline_pages/offline_internals.html7
-rw-r--r--chromium/chrome/browser/resources/offline_pages/offline_internals.js685
-rw-r--r--chromium/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js531
-rw-r--r--chromium/chrome/browser/resources/omnibox/BUILD.gn21
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox.html5
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox.js2
-rw-r--r--chromium/chrome/browser/resources/omnibox/omnibox_output.js29
-rw-r--r--chromium/chrome/browser/resources/omnibox/resources.grd58
-rw-r--r--chromium/chrome/browser/resources/pdf/BUILD.gn57
-rw-r--r--chromium/chrome/browser/resources/pdf/annotation_tool.js15
-rw-r--r--chromium/chrome/browser/resources/pdf/controller.js494
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/BUILD.gn118
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js)19
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/BUILD.gn17
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/BUILD.gn17
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/BUILD.gn19
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/BUILD.gn18
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/BUILD.gn17
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/BUILD.gn17
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html)10
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js)3
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn20
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js)5
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js)1
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-button.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js)0
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html)2
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.js (renamed from chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js)8
-rw-r--r--chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn25
-rw-r--r--chromium/chrome/browser/resources/pdf/index.html17
-rw-r--r--chromium/chrome/browser/resources/pdf/ink/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/pdf/ink/ink_api.js11
-rw-r--r--chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js13
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf_scripting_api.js185
-rw-r--r--chromium/chrome/browser/resources/pdf/pdf_viewer.js1482
-rw-r--r--chromium/chrome/browser/resources/pdf/toolbar_manager.js147
-rw-r--r--chromium/chrome/browser/resources/pdf/viewport.js22
-rw-r--r--chromium/chrome/browser/resources/pdf/viewport_scroller.js83
-rw-r--r--chromium/chrome/browser/resources/print_preview/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/BUILD.gn11
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination.js49
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination_match.html1
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination_match.js33
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/document_info.js9
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/local_parsers.html1
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/margins.js41
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/model.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/model.js185
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/scaling.html (renamed from chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.html)3
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/scaling.js24
-rw-r--r--chromium/chrome/browser/resources/print_preview/native_layer.js15
-rw-r--r--chromium/chrome/browser/resources/print_preview/polymer3/demo.js116
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview_resources.grd10
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview_utils.js2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/BUILD.gn7
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/advanced_options_settings.html1
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.html8
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.js35
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/app.html3
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/app.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html5
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js6
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_list_item.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_select.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_select.js2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/duplex_settings.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/duplex_settings.js2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/header.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/header_new.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/icons.html (renamed from chromium/chrome/browser/resources/print_preview/icons.html)13
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margin_control.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margin_control_container.js61
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margins_settings.html15
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/margins_settings.js7
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js3
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/pin_settings.js2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/preview_area.html1
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/preview_area.js89
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/scaling_settings.html7
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/scaling_settings.js126
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/sidebar.html7
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/sidebar.js2
-rw-r--r--chromium/chrome/browser/resources/quota_internals/OWNERS5
-rw-r--r--chromium/chrome/browser/resources/quota_internals/event_handler.js6
-rw-r--r--chromium/chrome/browser/resources/quota_internals/message_dispatcher.js2
-rw-r--r--chromium/chrome/browser/resources/reset_password/BUILD.gn3
-rw-r--r--chromium/chrome/browser/resources/reset_password/reset_password.html9
-rw-r--r--chromium/chrome/browser/resources/reset_password/reset_password.js21
-rw-r--r--chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py11
-rwxr-xr-xchromium/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py10
-rw-r--r--chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb17
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/BUILD.gn38
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/OWNERS3
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/sandbox_android_externs.js9
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html11
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.js20
-rw-r--r--chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js108
-rw-r--r--chromium/chrome/browser/resources/settings/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html29
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js30
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html48
-rw-r--r--chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js16
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/about_page.js4
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js29
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html2
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html39
-rw-r--r--chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js31
-rw-r--r--chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html5
-rw-r--r--chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html16
-rw-r--r--chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js2
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js53
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html10
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html17
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js62
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/payments_section.html14
-rw-r--r--chromium/chrome/browser/resources/settings/autofill_page/payments_section.js104
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.html3
-rw-r--r--chromium/chrome/browser/resources/settings/basic_page/basic_page.js5
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn5
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn21
-rw-r--r--chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/controls/controlled_button.html2
-rw-r--r--chromium/chrome/browser/resources/settings/controls/controlled_button.js32
-rw-r--r--chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html7
-rw-r--r--chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js1
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/BUILD.gn8
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/display.html8
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html31
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js31
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/keyboard.js2
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/pointers.html4
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage.html19
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage.js56
-rw-r--r--chromium/chrome/browser/resources/settings/device_page/storage_external.html2
-rw-r--r--chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html7
-rw-r--r--chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js17
-rw-r--r--chromium/chrome/browser/resources/settings/icons.html1
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/BUILD.gn7
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_config.html7
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_config.js47
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html20
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js266
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js39
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.html21
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_page.js173
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js20
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html1
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js6
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary.js2
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html2
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js25
-rw-r--r--chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js15
-rw-r--r--chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html7
-rw-r--r--chromium/chrome/browser/resources/settings/manifest.json2
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn1
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html22
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html1
-rw-r--r--chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js2
-rw-r--r--chromium/chrome/browser/resources/settings/os_settings_manifest.json2
-rw-r--r--chromium/chrome/browser/resources/settings/os_settings_resources.grd44
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/account_manager.html42
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/account_manager.js11
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html7
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/sync_page.js5
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/user_list.html6
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/user_list.js10
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html10
-rw-r--r--chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js58
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/BUILD.gn24
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html4
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html35
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js137
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js37
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html8
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers.html4
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers.js17
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js5
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html42
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js110
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html2
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js98
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html5
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js182
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html70
-rw-r--r--chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js225
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html17
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js102
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html19
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js4
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html94
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js128
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js45
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html9
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js4
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html1
-rw-r--r--chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js16
-rw-r--r--chromium/chrome/browser/resources/settings/route.js45
-rw-r--r--chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html5
-rw-r--r--chromium/chrome/browser/resources/settings/search_settings.js12
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html3
-rw-r--r--chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js15
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_resources.grd20
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html2
-rw-r--r--chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js4
-rw-r--r--chromium/chrome/browser/resources/settings/site_favicon.js2
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html4
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js20
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js21
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html8
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js42
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/constants.js8
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_data.html2
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_data.js18
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.html9
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_details.js14
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html7
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js51
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js9
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js13
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html11
-rw-r--r--chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js10
-rw-r--r--chromium/chrome/browser/resources/signin/BUILD.gn18
-rw-r--r--chromium/chrome/browser/resources/signin/signin_email_confirmation/signin_email_confirmation.html2
-rw-r--r--chromium/chrome/browser/resources/signin/signin_error/signin_error.html7
-rw-r--r--chromium/chrome/browser/resources/signin/signin_shared_css.html70
-rw-r--r--chromium/chrome/browser/resources/signin/signin_shared_css.js11
-rw-r--r--chromium/chrome/browser/resources/signin/signin_shared_old_css.html45
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/BUILD.gn48
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html6
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js44
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.html311
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.js18
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js114
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html3
-rw-r--r--chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.js7
-rw-r--r--chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp2
-rw-r--r--chromium/chrome/browser/resources/tab_strip/BUILD.gn22
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicator.html77
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicator.js19
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/picture_in_picture_alt.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/serial_port.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_muting_rounded.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_rounded.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_bluetooth_connected.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_capturing_with_arrow.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_recording.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_usb_connected.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/alert_indicators/vr_headset.svg1
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab.html248
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab.js80
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.html38
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.js307
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip.html25
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js39
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd60
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js72
-rw-r--r--chromium/chrome/browser/resources/tab_strip/types.js32
-rw-r--r--chromium/chrome/browser/resources/usb_internals/BUILD.gn21
-rw-r--r--chromium/chrome/browser/resources/usb_internals/resources.grd42
-rw-r--r--chromium/chrome/browser/resources/user_manager/shared_styles.html4
-rw-r--r--chromium/chrome/browser/resources/vr/OWNERS2
-rw-r--r--chromium/chrome/browser/resources/webapks/BUILD.gn5
-rw-r--r--chromium/chrome/browser/resources/webapks/about_webapks.html6
-rw-r--r--chromium/chrome/browser/resources/webapks/about_webapks.js21
-rw-r--r--chromium/chrome/browser/resources/welcome/BUILD.gn54
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn23
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.js108
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.html3
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.js23
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.html402
-rw-r--r--chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js72
-rw-r--r--chromium/chrome/browser/resources/welcome/landing_view.html65
-rw-r--r--chromium/chrome/browser/resources/welcome/landing_view.js28
-rw-r--r--chromium/chrome/browser/resources/welcome/landing_view_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/landing_view_proxy.js109
-rw-r--r--chromium/chrome/browser/resources/welcome/navigation_behavior.html6
-rw-r--r--chromium/chrome/browser/resources/welcome/navigation_behavior.js316
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn40
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.html3
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.js27
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.js162
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html403
-rw-r--r--chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js49
-rw-r--r--chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn25
-rw-r--r--chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html164
-rw-r--r--chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js37
-rw-r--r--chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.js159
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/BUILD.gn70
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/action_link_style.js9
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/action_link_style_css.html54
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/action_link_style_css.js17
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/animations_css.html66
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/animations_css.js9
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.js144
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.html68
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.js13
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/i18n_setup.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.js413
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html89
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/navi_colors_css.js12
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/nux_types.js8
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/onboarding_background.html367
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/onboarding_background.js7
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.html95
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.js12
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/step_indicator.html50
-rw-r--r--chromium/chrome/browser/resources/welcome/shared/step_indicator.js11
-rw-r--r--chromium/chrome/browser/resources/welcome/signin_view.html56
-rw-r--r--chromium/chrome/browser/resources/welcome/signin_view.js26
-rw-r--r--chromium/chrome/browser/resources/welcome/signin_view_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/signin_view_proxy.js123
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome.html4
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome.js7
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_app.html75
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_app.js37
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_browser_proxy.html2
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_browser_proxy.js73
-rw-r--r--chromium/chrome/browser/resources/welcome/welcome_resources.grd197
472 files changed, 13187 insertions, 7870 deletions
diff --git a/chromium/chrome/browser/resources/BUILD.gn b/chromium/chrome/browser/resources/BUILD.gn
index d1b6a8b7b45..8346f4fa503 100644
--- a/chromium/chrome/browser/resources/BUILD.gn
+++ b/chromium/chrome/browser/resources/BUILD.gn
@@ -3,7 +3,9 @@
# found in the LICENSE file.
import("//chrome/common/features.gni")
+import("//chrome/test/base/js2gtest.gni")
import("//tools/grit/grit_rule.gni")
+import("//tools/grit/repack.gni")
assert(!is_ios, "Chromium/iOS shouldn't use anything in //chrome")
@@ -19,11 +21,13 @@ if (closure_compile) {
"bluetooth_internals:closure_compile",
"bookmarks:closure_compile",
"discards:closure_compile",
+ "download_internals:closure_compile",
"downloads:closure_compile",
"history:closure_compile",
"local_ntp:closure_compile",
"local_state:closure_compile",
"management:closure_compile",
+ "media_router:closure_compile",
"ntp4:closure_compile",
"omnibox:closure_compile",
"pdf:closure_compile",
@@ -36,6 +40,9 @@ if (closure_compile) {
"welcome:closure_compile",
]
}
+ if (is_win || is_android || is_linux) {
+ deps += [ "sandbox_internals:closure_compile" ]
+ }
if (is_chromeos) {
deps += [ "chromeos:closure_compile" ]
}
@@ -103,6 +110,18 @@ grit("webapks_ui_resources") {
if (!is_android) {
grit("component_extension_resources") {
source = "component_extension_resources.grd"
+
+ # The .grd contains references to generated files.
+ source_is_generated = true
+ grit_flags = [
+ "-E",
+ "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+ ]
+
+ deps = [
+ "//chrome/browser/resources/pdf/elements:polymer3_elements",
+ ]
+
defines = chrome_grit_defines
if (enable_hangout_services_extension) {
defines += [ "enable_hangout_services_extension" ]
@@ -224,6 +243,17 @@ if (!is_android && !is_chromeos) {
grit("welcome_resources") {
source = "welcome/welcome_resources.grd"
+ # The .grd contains references to generated files.
+ source_is_generated = true
+
+ deps = [
+ "//chrome/browser/resources/welcome:polymer3_elements",
+ ]
+ grit_flags = [
+ "-E",
+ "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+ ]
+
defines = chrome_grit_defines
outputs = [
"grit/welcome_resources.h",
@@ -327,3 +357,52 @@ if (enable_webui_tab_strip) {
]
}
}
+
+repack("dev_ui_paks") {
+ output = "$root_gen_dir/chrome/dev_ui_page_resources.pak"
+
+ sources = [
+ "$root_gen_dir/chrome/bluetooth_internals_resources.pak",
+ "$root_gen_dir/chrome/omnibox_resources.pak",
+ "$root_gen_dir/chrome/usb_internals_resources.pak",
+ "$root_gen_dir/components/sync_driver_resources.pak",
+ ]
+ deps = [
+ "//chrome/browser/resources/bluetooth_internals:resources",
+ "//chrome/browser/resources/omnibox:resources",
+ "//chrome/browser/resources/usb_internals:resources",
+ "//components/sync/driver:resources",
+ ]
+}
+
+# TODO(https://crbug.com/930109): Figure out why this test fails on MAC ASAN.
+if (!is_asan || !is_mac) {
+ js2gtest("resources_unitjs_tests") {
+ test_type = "webui"
+ sources = [
+ "gaia_auth_host/password_change_authenticator_test.unitjs",
+ ]
+
+ # This has to be a gen_include, so it doesn't collide with other js2gtests
+ gen_include_files = [ "//ui/webui/resources/js/cr.js" ]
+
+ # But these have to be extra_js_files, since it uses a native object
+ # EventTarget, which doesn't work at compile time.
+ extra_js_files = [
+ "//ui/webui/resources/js/cr/event_target.js",
+ "gaia_auth_host/password_change_authenticator.js",
+ ]
+ defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+ }
+
+ source_set("browser_tests") {
+ testonly = true
+ deps = [
+ ":resources_unitjs_tests",
+ ]
+ }
+} else {
+ source_set("browser_tests") {
+ testonly = true
+ }
+}
diff --git a/chromium/chrome/browser/resources/accessibility/accessibility.html b/chromium/chrome/browser/resources/accessibility/accessibility.html
index 478c0c27385..1d9b645429c 100644
--- a/chromium/chrome/browser/resources/accessibility/accessibility.html
+++ b/chromium/chrome/browser/resources/accessibility/accessibility.html
@@ -17,11 +17,20 @@ found in the LICENSE file.
</head>
<body>
<h1>Accessibility Internals</h1>
+ <p>
+ Use this page to inspect the internal representation of accessibility in
+ Chrome. You can see and modify the various accessibility modes Chrome has.
+ You can also view the accessibility tree for a specific page, or for the
+ Chrome app natively.
+ </p>
<div class="columns">
<div class="column">
- <h2>Global accessibility mode:</h2>
-
+ <h2>Accessibility modes:</h2>
+ <p>
+ Check/uncheck accessibility modes to see how they change a page's
+ accessibility.
+ </p>
<div class="checkbox-row">
<label>
<span class="checkbox-wrapper">
@@ -103,8 +112,25 @@ found in the LICENSE file.
Automatically labels images.
</div>
- <h2>Options:</h2>
+ <h2>Command line options:</h2>
+ <p>
+ Accessibility features in Chrome are off by default and enabled
+ automatically on-demand. Changes to these modes only take effect
+ until the next time Chrome is restarted.
+ </p>
+ <p>
+ To force accessibility to be enabled at launch, run Chrome with this
+ flag:
+ <pre>--force-renderer-accessibility</pre>
+ </p>
+ <p>
+ To disable accessibility, run Chrome with this flag:
+ <pre>--disable-renderer-accessibility</pre>
+ </p>
+ </div>
+ <div class="column">
+ <h2>Accessibility tree viewing options:</h2>
<div class="checkbox-row">
<span class="checkbox-wrapper">
<input type="checkbox" id="internal"
@@ -118,37 +144,47 @@ found in the LICENSE file.
Show internal accessibility tree instead of native
</div>
- </div>
- <div class="column">
- <p>
- Accessibility features in Chrome are off by default and enabled
- automatically on-demand. Changes to this page only take effect
- until the next time Chrome is restarted.
- </p>
+ <h3>Filters:</h3>
<p>
- To force accessibility to be enabled at launch, run Chrome with this
- command-line flag:
- <pre>--force-renderer-accessibility</pre>
- </p>
- <p>
- To disable accessibility, run Chrome with this flag:
- <pre>--disable-renderer-accessibility</pre>
+ Use filters to match the attributes and attribute values you want
+ included in the output. Filters can contain simple wildcards (*) only,
+ they're not regular expressions. Attributes are separated by spaces.
</p>
- </div>
- </div>
- <!--
- <div id="global" class="row">Global accessibility mode:
- <a is="action-link" role="button" id="toggle_global"
- aria-labelledby="global"></a>
- </div>
+ <div>
+ <label for="filter-allow">
+ Allow:
+ </label>
+ <input id="filter-allow" aria-describedby="allow_secondary">
+ </div>
+ <div id="allow_secondary" class="secondary">
+ Include these attributes. Empty attributes are skipped.
+ </div>
- <div id="internal" class="row">
- Show internal accessibility tree instead of native:
- <a is="action-link" role="button" id="toggle_internal"
- aria-labelledby="internal"></a>
+ <div>
+ <label for="filter-allow-empty">
+ Allow empty:
+ </label>
+ <input id="filter-allow-empty"
+ aria-describedby="allow-empty_secondary">
+ </div>
+ <div id="allow-empty_secondary" class="secondary">
+ Include these attributes, even if they are empty.
+ </div>
+
+ <div>
+ <label for="filter-deny">
+ Deny:
+ </label>
+ <input id="filter-deny" aria-describedby="deny_secondary">
+ </div>
+ <div id="deny_secondary" class="secondary">
+ Exclude these attributes.
+ </div>
+
+ </div>
</div>
--->
+
<h2>Chrome Native UI:</h2>
<div id="browsers" class="list">
Set a delay, in milliseconds, before getting the native accessibility tree:
diff --git a/chromium/chrome/browser/resources/accessibility/accessibility.js b/chromium/chrome/browser/resources/accessibility/accessibility.js
index e5f19928733..7db0aafd5e0 100644
--- a/chromium/chrome/browser/resources/accessibility/accessibility.js
+++ b/chromium/chrome/browser/resources/accessibility/accessibility.js
@@ -57,15 +57,24 @@ cr.define('accessibility', function() {
const tree = $(id + ':tree');
// If the tree is visible, request a new tree with the updated mode.
const shouldRequestTree = !!tree && tree.style.display != 'none';
- chrome.send('toggleAccessibility', [
- String(data.processId), String(data.routeId), mode,
- String(shouldRequestTree)
- ]);
+ chrome.send('toggleAccessibility', [{
+ 'processId': data.processId,
+ 'routeId': data.routeId,
+ 'modeId': mode,
+ 'shouldRequestTree': shouldRequestTree
+ }]);
}
function requestTree(data, element) {
+ const allow = $('filter-allow').value;
+ const allowEmpty = $('filter-allow-empty').value;
+ const deny = $('filter-deny').value;
+ window.localStorage['chrome-accessibility-filter-allow'] = allow;
+ window.localStorage['chrome-accessibility-filter-allow-empty'] = allowEmpty;
+ window.localStorage['chrome-accessibility-filter-deny'] = deny;
+
// The calling |element| is a button with an id of the format
- // <treeId>:<requestType>, where requestType is one of 'showTree',
+ // <treeId>:<requestType>, where requestType is one of 'showOrRefreshTree',
// 'copyTree'. Send the request type to C++ so is calls the corresponding
// function with the result.
const requestType = element.id.split(':')[1];
@@ -73,12 +82,21 @@ cr.define('accessibility', function() {
const delay = $('native_ui_delay').value;
setTimeout(() => {
chrome.send(
- 'requestNativeUITree', [String(data.sessionId), requestType]);
+ 'requestNativeUITree', [{
+ 'sessionId': data.sessionId,
+ 'requestType': requestType,
+ 'filters':
+ {'allow': allow, 'allowEmpty': allowEmpty, 'deny': deny}
+ }]);
}, delay);
} else {
chrome.send(
- 'requestWebContentsTree',
- [String(data.processId), String(data.routeId), requestType]);
+ 'requestWebContentsTree', [{
+ 'processId': data.processId,
+ 'routeId': data.routeId,
+ 'requestType': requestType,
+ 'filters': {'allow': allow, 'allowEmpty': allowEmpty, 'deny': deny}
+ }]);
}
}
@@ -91,7 +109,7 @@ cr.define('accessibility', function() {
bindCheckbox('text', data['text']);
bindCheckbox('screenreader', data['screenreader']);
bindCheckbox('html', data['html']);
- bindCheckbox('label_images', data['label_images']);
+ bindCheckbox('label_images', data['labelImages']);
bindCheckbox('internal', data['internal']);
$('pages').textContent = '';
@@ -105,6 +123,15 @@ cr.define('accessibility', function() {
for (let i = 0; i < browsers.length; i++) {
addToBrowsersList(browsers[i]);
}
+
+ // Cache filters so they're easily accessible on page refresh.
+ const allow = window.localStorage['chrome-accessibility-filter-allow'];
+ const allowEmpty =
+ window.localStorage['chrome-accessibility-filter-allow-empty'];
+ const deny = window.localStorage['chrome-accessibility-filter-deny'];
+ $('filter-allow').value = allow ? allow : '*';
+ $('filter-allow-empty').value = allowEmpty ? allowEmpty : '';
+ $('filter-deny').value = deny ? deny : '';
}
function bindCheckbox(name, value) {
@@ -116,7 +143,8 @@ cr.define('accessibility', function() {
$(name).labels[0].classList.add('disabled');
}
$(name).addEventListener('change', function() {
- chrome.send('setGlobalFlag', [name, $(name).checked]);
+ chrome.send(
+ 'setGlobalFlag', [{'flagName': name, 'enabled': $(name).checked}]);
document.location.reload();
});
}
@@ -157,7 +185,7 @@ cr.define('accessibility', function() {
if (data.type == 'page') {
const siteInfo = document.createElement('div');
- const properties = ['favicon_url', 'name', 'url'];
+ const properties = ['faviconUrl', 'name', 'url'];
for (let j = 0; j < properties.length; j++) {
siteInfo.appendChild(formatValue(data, properties[j]));
}
@@ -169,7 +197,7 @@ cr.define('accessibility', function() {
row.appendChild(createModeElement(AXMode.kScreenReader, data, 'web'));
row.appendChild(createModeElement(AXMode.kHTML, data, 'web'));
row.appendChild(
- createModeElement(AXMode.kLabelImages, data, 'label_images'));
+ createModeElement(AXMode.kLabelImages, data, 'labelImages'));
} else {
const siteInfo = document.createElement('span');
siteInfo.appendChild(formatValue(data, 'name'));
@@ -200,7 +228,7 @@ cr.define('accessibility', function() {
function formatValue(data, property) {
const value = data[property];
- if (property == 'favicon_url') {
+ if (property == 'faviconUrl') {
const faviconElement = document.createElement('img');
if (value) {
faviconElement.src = value;
@@ -245,7 +273,7 @@ cr.define('accessibility', function() {
}
function createModeElement(mode, data, globalStateName) {
- const currentMode = data['a11y_mode'];
+ const currentMode = data['a11yMode'];
const link = document.createElement('a', 'action-link');
link.setAttribute('role', 'button');
@@ -282,7 +310,7 @@ cr.define('accessibility', function() {
} else {
show.textContent = 'Show accessibility tree';
}
- show.id = id + ':showTree';
+ show.id = id + ':showOrRefreshTree';
show.setAttribute('aria-expanded', String(opt_refresh));
show.addEventListener('click', requestTree.bind(this, data, show));
return show;
@@ -293,7 +321,7 @@ cr.define('accessibility', function() {
hide.textContent = 'Hide accessibility tree';
hide.id = id + ':hideTree';
hide.addEventListener('click', function() {
- const show = $(id + ':showTree');
+ const show = $(id + ':showOrRefreshTree');
show.textContent = 'Show accessibility tree';
show.setAttribute('aria-expanded', 'false');
show.focus();
@@ -335,7 +363,7 @@ cr.define('accessibility', function() {
}
// Called from C++
- function showTree(data) {
+ function showOrRefreshTree(data) {
const id = getIdFromData(data);
const row = $(id);
if (!row) {
@@ -344,7 +372,7 @@ cr.define('accessibility', function() {
row.textContent = '';
formatRow(row, data);
- $(id + ':hideTree').focus();
+ $(id + ':showOrRefreshTree').focus();
}
// Called from C++
@@ -371,11 +399,11 @@ cr.define('accessibility', function() {
console.error('Unable to copy accessibility tree.', data.error);
}
-
const tree = $(id + ':tree');
// If the tree is currently shown, update it since it may have changed.
if (tree && tree.style.display != 'none') {
- showTree(data);
+ showOrRefreshTree(data);
+ $(id + ':copyTree').focus();
}
}
@@ -401,7 +429,11 @@ cr.define('accessibility', function() {
}
// These are the functions we export so they can be called from C++.
- return {copyTree: copyTree, initialize: initialize, showTree: showTree};
+ return {
+ copyTree: copyTree,
+ initialize: initialize,
+ showOrRefreshTree: showOrRefreshTree
+ };
});
document.addEventListener('DOMContentLoaded', accessibility.initialize);
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn b/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
index 7ab5c808a39..d53ec0f8316 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
+++ b/chromium/chrome/browser/resources/bluetooth_internals/BUILD.gn
@@ -17,6 +17,7 @@ js_library("bluetooth_internals") {
"adapter_page.js",
"bluetooth_internals.js",
"characteristic_list.js",
+ "debug_log_page.js",
"descriptor_list.js",
"device_broker.js",
"device_collection.js",
@@ -32,14 +33,33 @@ js_library("bluetooth_internals") {
]
deps = [
+ ":page",
+ ":page_manager",
"//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_js_library_for_compile",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:util",
"//ui/webui/resources/js/cr/ui:array_data_model",
"//ui/webui/resources/js/cr/ui:list",
"//ui/webui/resources/js/cr/ui:list_item",
- "//ui/webui/resources/js/cr/ui/page_manager:page",
- "//ui/webui/resources/js/cr/ui/page_manager:page_manager",
+ ]
+}
+
+js_library("page") {
+ deps = [
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js/cr:event_target",
+ "//ui/webui/resources/js/cr/ui:bubble",
+ "//ui/webui/resources/js/cr/ui:focus_outline_manager",
+ "//ui/webui/resources/js/cr/ui:node_utils",
+ "//ui/webui/resources/js/cr/ui:overlay",
+ ]
+}
+
+js_library("page_manager") {
+ deps = [
+ ":page",
+ "//ui/webui/resources/js:cr",
]
}
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
index 0da84a773fe..1ca5ea685c5 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -154,15 +154,18 @@ cr.define('adapter_broker', function() {
/**
* Initializes an AdapterBroker if one doesn't exist.
+ * @param {!mojom.BluetoothInternalsHandlerRemote=}
+ * opt_bluetoothInternalsHandler
* @return {!Promise<!adapter_broker.AdapterBroker>} resolves with
* AdapterBroker, rejects if Bluetooth is not supported.
*/
- function getAdapterBroker() {
+ function getAdapterBroker(opt_bluetoothInternalsHandler) {
if (adapterBroker) {
return Promise.resolve(adapterBroker);
}
- const bluetoothInternalsHandler =
+ const bluetoothInternalsHandler = opt_bluetoothInternalsHandler ?
+ opt_bluetoothInternalsHandler :
mojom.BluetoothInternalsHandler.getRemote();
// Get an Adapter service.
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
index fdd34a71f54..1e4063113f5 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
+++ b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.html
@@ -20,8 +20,10 @@
<link rel="import" href="chrome://resources/html/cr/ui/list_item.html">
<link rel="import" href="chrome://resources/html/cr/ui/list.html">
<link rel="import" href="chrome://resources/html/cr/ui/overlay.html">
- <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page_manager.html">
- <link rel="import" href="chrome://resources/html/cr/ui/page_manager/page.html">
+
+ <link rel="import" href="page_manager.html">
+ <link rel="import" href="page.html">
+
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
@@ -39,6 +41,7 @@
<script src="service_list.js"></script>
<script src="descriptor_list.js"></script>
<script src="adapter_page.js"></script>
+ <script src="debug_log_page.js"></script>
<script src="device_collection.js"></script>
<script src="device_details_page.js"></script>
<script src="device_table.js"></script>
@@ -63,6 +66,9 @@
<button id="scan-btn">Start Scan</button>
</div>
</section>
+ <section id="debug" hidden>
+ <div class="header-extras" id="debug-container"></div>
+ </section>
</div>
<div id="snackbar-container"></div>
<aside id="sidebar">
@@ -79,6 +85,9 @@
<li data-page-name="devices">
<button class="custom-appearance">Devices</button>
</li>
+ <li data-page-name="debug" data-page-name="debug">
+ <button class="custom-appearance">Debug Logs</button>
+ </li>
</ul>
</nav>
</section>
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
index de4b6d0a4d9..e146a8e1746 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
+++ b/chromium/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
@@ -19,6 +19,7 @@ cr.define('bluetooth_internals', function() {
const AdapterPage = adapter_page.AdapterPage;
const DeviceDetailsPage = device_details_page.DeviceDetailsPage;
const DevicesPage = devices_page.DevicesPage;
+ const DebugLogPage = debug_log_page.DebugLogPage;
const PageManager = cr.ui.pageManager.PageManager;
const Snackbar = snackbar.Snackbar;
const SnackbarType = snackbar.SnackbarType;
@@ -29,6 +30,8 @@ cr.define('bluetooth_internals', function() {
let adapterPage = null;
/** @type {devices_page.DevicesPage} */
let devicesPage = null;
+ /** @type {debug_log_page.DebugLogPage} */
+ let debugLogPage = null;
/** @type {bluetooth.mojom.DiscoverySessionRemote} */
let discoverySession = null;
@@ -36,6 +39,9 @@ cr.define('bluetooth_internals', function() {
/** @type {boolean} */
let userRequestedScanStop = false;
+ /** @type {!mojom.BluetoothInternalsHandlerRemote} */
+ const bluetoothInternalsHandler = mojom.BluetoothInternalsHandler.getRemote();
+
/**
* Observer for page changes. Used to update page title header.
* @constructor
@@ -258,6 +264,8 @@ cr.define('bluetooth_internals', function() {
PageManager.register(devicesPage);
adapterPage = new AdapterPage();
PageManager.register(adapterPage);
+ debugLogPage = new DebugLogPage(bluetoothInternalsHandler);
+ PageManager.register(debugLogPage);
// Set up hash-based navigation.
window.addEventListener('hashchange', function() {
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/debug_log_page.js b/chromium/chrome/browser/resources/bluetooth_internals/debug_log_page.js
new file mode 100644
index 00000000000..5c13a39a26e
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/debug_log_page.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.
+
+/**
+ * Javascript for DebugLogPage, served from chrome://bluetooth-internals/.
+ */
+cr.define('debug_log_page', function() {
+ /** @const {string} */
+ const LOGS_NOT_SUPPORTED_STRING = 'Debug logs not supported';
+
+ /**
+ * Page that allows user to enable/disable debug logs.
+ */
+ class DebugLogPage extends cr.ui.pageManager.Page {
+ /**
+ * @param {!mojom.BluetoothInternalsHandlerRemote} bluetoothInternalsHandler
+ */
+ constructor(bluetoothInternalsHandler) {
+ super('debug', 'Debug Logs', 'debug');
+
+ /**
+ * @private {?mojom.DebugLogsChangeHandlerRemote}
+ */
+ this.debugLogsChangeHandler_ = null;
+
+ /** @private {?HTMLInputElement} */
+ this.inputElement_ = null;
+
+ /** @private {!HTMLDivElement} */
+ this.debugContainer_ =
+ /** @type {!HTMLDivElement} */ ($('debug-container'));
+
+ bluetoothInternalsHandler.getDebugLogsChangeHandler().then((params) => {
+ if (params.handler) {
+ this.setUpInput(params.handler, params.initialToggleValue);
+ } else {
+ this.debugContainer_.textContent = LOGS_NOT_SUPPORTED_STRING;
+ }
+ });
+ }
+
+ /**
+ * @param {!mojom.DebugLogsChangeHandlerRemote} handler
+ * @param {boolean} initialInputValue
+ */
+ setUpInput(handler, initialInputValue) {
+ this.debugLogsChangeHandler_ = handler;
+
+ this.inputElement_ =
+ /** @type {!HTMLInputElement} */ (document.createElement('input'));
+ this.inputElement_.setAttribute('type', 'checkbox');
+ this.inputElement_.checked = initialInputValue;
+ this.inputElement_.addEventListener(
+ 'change', this.onToggleChange.bind(this));
+ this.debugContainer_.appendChild(this.inputElement_);
+ }
+
+ onToggleChange() {
+ this.debugLogsChangeHandler_.changeDebugLogsState(
+ this.inputElement_.checked);
+ }
+ }
+
+ return {
+ DebugLogPage: DebugLogPage,
+ };
+});
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/page.html b/chromium/chrome/browser/resources/bluetooth_internals/page.html
new file mode 100644
index 00000000000..f6e2de85f42
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/page.html
@@ -0,0 +1 @@
+<script src="page.js"></script>
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/page.js b/chromium/chrome/browser/resources/bluetooth_internals/page.js
new file mode 100644
index 00000000000..6c40a9ea35e
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/page.js
@@ -0,0 +1,314 @@
+// Copyright 2014 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.
+
+// <include src="../node_utils.js">
+
+cr.define('cr.ui.pageManager', function() {
+ const PageManager = cr.ui.pageManager.PageManager;
+
+ /**
+ * Base class for pages that can be shown and hidden by PageManager. Each Page
+ * is like a node in a forest, corresponding to a particular div. At any
+ * point, one root Page is visible, and any visible Page can show a child Page
+ * as an overlay. The host of the root Page(s) should provide a container div
+ * for each nested level to enforce the stack order of overlays.
+ */
+ class Page extends cr.EventTarget {
+ /**
+ * @param {string} name Page name.
+ * @param {string} title Page title, used for history.
+ * @param {string} pageDivName ID of the div corresponding to the page.
+ */
+ constructor(name, title, pageDivName) {
+ super();
+
+ this.name = name;
+ this.title = title;
+ this.pageDivName = pageDivName;
+ this.pageDiv = getRequiredElement(this.pageDivName);
+ // |pageDiv.page| is set to the page object (this) when the page is
+ // visible to track which page is being shown when multiple pages can
+ // share the same underlying div.
+ this.pageDiv.page = null;
+ this.tab = null;
+ this.lastFocusedElement = null;
+ this.hash = '';
+
+ /**
+ * The parent page of this page; or null for root pages.
+ * @type {cr.ui.pageManager.Page}
+ */
+ this.parentPage = null;
+
+ /**
+ * The section on the parent page that is associated with this page.
+ * Can be null.
+ * @type {Element}
+ */
+ this.associatedSection = null;
+
+ /**
+ * An array of controls that are associated with this page. The first
+ * control should be located on a root page.
+ * @type {Array<Element>}
+ */
+ this.associatedControls = null;
+
+ /**
+ * If true; this page should always be considered the top-most page when
+ * visible.
+ * @private {boolean}
+ */
+ this.alwaysOnTop_ = false;
+
+ /**
+ * Set this to handle cancelling an overlay (and skip some typical steps).
+ * @see {cr.ui.PageManager.prototype.cancelOverlay}
+ * @type {?Function}
+ */
+ this.handleCancel = null;
+
+ /** @type {boolean} */
+ this.isOverlay = false;
+ }
+
+ /**
+ * Initializes page content.
+ */
+ initializePage() {}
+
+ /**
+ * Called by the PageManager when this.hash changes while the page is
+ * already visible. This is analogous to the hashchange DOM event.
+ */
+ didChangeHash() {}
+
+ /**
+ * Sets focus on the first focusable element. Override for a custom focus
+ * strategy.
+ */
+ focus() {
+ cr.ui.setInitialFocus(this.pageDiv);
+ }
+
+ /**
+ * Reverse any buttons strips in this page (only applies to overlays).
+ * @see cr.ui.reverseButtonStrips for an explanation of why this is
+ * necessary and when it's done.
+ */
+ reverseButtonStrip() {
+ assert(this.isOverlay);
+ cr.ui.reverseButtonStrips(this.pageDiv);
+ }
+
+ /**
+ * Whether it should be possible to show the page.
+ * @return {boolean} True if the page should be shown.
+ */
+ canShowPage() {
+ return true;
+ }
+
+ /**
+ * Updates the hash of the current page. If the page is topmost, the history
+ * state is updated.
+ * @param {string} hash The new hash value. Like location.hash, this
+ * should include the leading '#' if not empty.
+ */
+ setHash(hash) {
+ if (this.hash == hash) {
+ return;
+ }
+ this.hash = hash;
+ PageManager.onPageHashChanged(this);
+ }
+
+ /**
+ * Called after the page has been shown.
+ */
+ didShowPage() {}
+
+ /**
+ * Called before the page will be hidden, e.g., when a different root page
+ * will be shown.
+ */
+ willHidePage() {}
+
+ /**
+ * Called after the overlay has been closed.
+ */
+ didClosePage() {}
+
+ /**
+ * Gets the container div for this page if it is an overlay.
+ * @type {HTMLDivElement}
+ */
+ get container() {
+ assert(this.isOverlay);
+ return this.pageDiv.parentNode;
+ }
+
+ /**
+ * Gets page visibility state.
+ * @type {boolean}
+ */
+ get visible() {
+ // If this is an overlay dialog it is no longer considered visible while
+ // the overlay is fading out. See http://crbug.com/118629.
+ if (this.isOverlay && this.container.classList.contains('transparent')) {
+ return false;
+ }
+ if (this.pageDiv.hidden) {
+ return false;
+ }
+ return this.pageDiv.page == this;
+ }
+
+ /**
+ * Sets page visibility.
+ * @type {boolean}
+ */
+ set visible(visible) {
+ if ((this.visible && visible) || (!this.visible && !visible)) {
+ return;
+ }
+
+ // If using an overlay, the visibility of the dialog is toggled at the
+ // same time as the overlay to show the dialog's out transition. This
+ // is handled in setOverlayVisible.
+ if (this.isOverlay) {
+ this.setOverlayVisible_(visible);
+ } else {
+ this.pageDiv.page = this;
+ this.pageDiv.hidden = !visible;
+ PageManager.onPageVisibilityChanged(this);
+ }
+
+ cr.dispatchPropertyChange(this, 'visible', visible, !visible);
+ }
+
+ /**
+ * Whether the page is considered 'sticky', such that it will remain a root
+ * page even if sub-pages change.
+ * @type {boolean} True if this page is sticky.
+ */
+ get sticky() {
+ return false;
+ }
+
+ /**
+ * @type {boolean} True if this page should always be considered the
+ * top-most page when visible.
+ */
+ get alwaysOnTop() {
+ return this.alwaysOnTop_;
+ }
+
+ /**
+ * @type {boolean} True if this page should always be considered the
+ * top-most page when visible. Only overlays can be always on top.
+ */
+ set alwaysOnTop(value) {
+ assert(this.isOverlay);
+ this.alwaysOnTop_ = value;
+ }
+
+ /**
+ * Shows or hides an overlay (including any visible dialog).
+ * @param {boolean} visible Whether the overlay should be visible or not.
+ * @private
+ */
+ setOverlayVisible_(visible) {
+ assert(this.isOverlay);
+ const pageDiv = this.pageDiv;
+ const container = this.container;
+
+ if (container.hidden != visible) {
+ if (visible) {
+ // If the container is set hidden and then immediately set visible
+ // again, the fadeCompleted_ callback would cause it to be erroneously
+ // hidden again. Removing the transparent tag avoids that.
+ container.classList.remove('transparent');
+
+ // Hide all dialogs in this container since a different one may have
+ // been previously visible before fading out.
+ const pages = container.querySelectorAll('.page');
+ for (let i = 0; i < pages.length; i++) {
+ pages[i].hidden = true;
+ }
+ // Show the new dialog.
+ pageDiv.hidden = false;
+ pageDiv.page = this;
+ }
+ return;
+ }
+
+ const self = this;
+ const loading = PageManager.isLoading();
+ if (!loading) {
+ // TODO(flackr): Use an event delegate to avoid having to subscribe and
+ // unsubscribe for transitionend events.
+ container.addEventListener('transitionend', function f(e) {
+ const propName = e.propertyName;
+ if (e.target != e.currentTarget ||
+ (propName && propName != 'opacity')) {
+ return;
+ }
+ container.removeEventListener('transitionend', f);
+ self.fadeCompleted_();
+ });
+ // transition is 200ms. Let's wait for 400ms.
+ ensureTransitionEndEvent(container, 400);
+ }
+
+ if (visible) {
+ container.hidden = false;
+ pageDiv.hidden = false;
+ pageDiv.page = this;
+ // NOTE: This is a hacky way to force the container to layout which
+ // will allow us to trigger the transition.
+ /** @suppress {uselessCode} */
+ container.scrollTop;
+
+ this.pageDiv.removeAttribute('aria-hidden');
+ if (this.parentPage) {
+ this.parentPage.pageDiv.parentElement.setAttribute(
+ 'aria-hidden', true);
+ }
+ container.classList.remove('transparent');
+ PageManager.onPageVisibilityChanged(this);
+ } else {
+ // Kick change events for text fields.
+ if (pageDiv.contains(document.activeElement)) {
+ document.activeElement.blur();
+ }
+ container.classList.add('transparent');
+ }
+
+ if (loading) {
+ this.fadeCompleted_();
+ }
+ }
+
+ /**
+ * Called when a container opacity transition finishes.
+ * @private
+ */
+ fadeCompleted_() {
+ if (this.container.classList.contains('transparent')) {
+ this.pageDiv.hidden = true;
+ this.container.hidden = true;
+
+ if (this.parentPage) {
+ this.parentPage.pageDiv.parentElement.removeAttribute('aria-hidden');
+ }
+
+ PageManager.onPageVisibilityChanged(this);
+ }
+ }
+ }
+
+ // Export
+ return {Page: Page};
+});
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/page_manager.html b/chromium/chrome/browser/resources/bluetooth_internals/page_manager.html
new file mode 100644
index 00000000000..5ce86ea9086
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/page_manager.html
@@ -0,0 +1 @@
+<script src="page_manager.js"></script>
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/page_manager.js b/chromium/chrome/browser/resources/bluetooth_internals/page_manager.js
new file mode 100644
index 00000000000..bca2b6dbb76
--- /dev/null
+++ b/chromium/chrome/browser/resources/bluetooth_internals/page_manager.js
@@ -0,0 +1,800 @@
+// Copyright 2014 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('cr.ui.pageManager', function() {
+ /**
+ * PageManager contains a list of root Page and overlay Page objects and
+ * handles "navigation" by showing and hiding these pages and overlays. On
+ * initial load, PageManager can use the path to open the correct hierarchy
+ * of pages and overlay(s). Handlers for user events, like pressing buttons,
+ * can call into PageManager to open a particular overlay or cancel an
+ * existing overlay.
+ */
+ const PageManager = {
+ /**
+ * True if page is served from a dialog.
+ * @type {boolean}
+ */
+ isDialog: false,
+
+ /**
+ * Offset of page container in pixels. Uber pages that use the side menu
+ * can override this with the setter.
+ * @type {number}
+ */
+ horizontalOffset_: 23,
+
+ /**
+ * Root pages. Maps lower-case page names to the respective page object.
+ * @type {!Object<!cr.ui.pageManager.Page>}
+ */
+ registeredPages: {},
+
+ /**
+ * Pages which are meant to behave like modal dialogs. Maps lower-case
+ * overlay names to the respective overlay object.
+ * @type {!Object<!cr.ui.pageManager.Page>}
+ * @private
+ */
+ registeredOverlayPages: {},
+
+ /**
+ * Observers will be notified when opening and closing overlays.
+ * @type {!Array<!cr.ui.pageManager.PageManager.Observer>}
+ */
+ observers_: [],
+
+ /**
+ * Initializes the complete page.
+ * @param {cr.ui.pageManager.Page} defaultPage The page to be shown when no
+ * page is specified in the path.
+ */
+ initialize: function(defaultPage) {
+ this.defaultPage_ = defaultPage;
+
+ cr.ui.FocusOutlineManager.forDocument(document);
+ document.addEventListener('scroll', this.handleScroll_.bind(this));
+
+ // Trigger the scroll handler manually to set the initial state.
+ this.handleScroll_();
+
+ // Shake the dialog if the user clicks outside the dialog bounds.
+ const containers = /** @type {!NodeList<!HTMLElement>} */ (
+ document.querySelectorAll('body > .overlay'));
+ for (let i = 0; i < containers.length; i++) {
+ const overlay = containers[i];
+ cr.ui.overlay.setupOverlay(overlay);
+ overlay.addEventListener(
+ 'cancelOverlay', this.cancelOverlay.bind(this));
+ }
+
+ cr.ui.overlay.globalInitialization();
+ },
+
+ /**
+ * Registers new page.
+ * @param {!cr.ui.pageManager.Page} page Page to register.
+ */
+ register: function(page) {
+ this.registeredPages[page.name.toLowerCase()] = page;
+ page.initializePage();
+ },
+
+ /**
+ * Unregisters an existing page.
+ * @param {!cr.ui.pageManager.Page} page Page to unregister.
+ */
+ unregister: function(page) {
+ delete this.registeredPages[page.name.toLowerCase()];
+ },
+
+ /**
+ * Registers a new Overlay page.
+ * @param {!cr.ui.pageManager.Page} overlay Overlay to register.
+ * @param {cr.ui.pageManager.Page} parentPage Associated parent page for
+ * this overlay.
+ * @param {Array} associatedControls Array of control elements associated
+ * with this page.
+ */
+ registerOverlay: function(overlay, parentPage, associatedControls) {
+ this.registeredOverlayPages[overlay.name.toLowerCase()] = overlay;
+ overlay.parentPage = parentPage;
+ if (associatedControls) {
+ overlay.associatedControls = associatedControls;
+ if (associatedControls.length) {
+ overlay.associatedSection =
+ this.findSectionForNode_(associatedControls[0]);
+ }
+
+ // Sanity check.
+ for (let i = 0; i < associatedControls.length; ++i) {
+ assert(associatedControls[i], 'Invalid element passed.');
+ }
+ }
+
+ overlay.tab = undefined;
+ overlay.isOverlay = true;
+
+ overlay.reverseButtonStrip();
+ overlay.initializePage();
+ },
+
+ /**
+ * Shows the default page.
+ * @param {boolean=} opt_updateHistory If we should update the history after
+ * showing the page (defaults to true).
+ */
+ showDefaultPage: function(opt_updateHistory) {
+ assert(
+ this.defaultPage_ instanceof cr.ui.pageManager.Page,
+ 'PageManager must be initialized with a default page.');
+ this.showPageByName(this.defaultPage_.name, opt_updateHistory);
+ },
+
+ /**
+ * Shows a registered page. This handles both root and overlay pages.
+ * @param {string} pageName Page name.
+ * @param {boolean=} opt_updateHistory If we should update the history after
+ * showing the page (defaults to true).
+ * @param {Object=} opt_propertyBag An optional bag of properties including
+ * replaceState (if history state should be replaced instead of pushed).
+ * hash (a hash state to attach to the page).
+ */
+ showPageByName: function(pageName, opt_updateHistory, opt_propertyBag) {
+ opt_updateHistory = opt_updateHistory !== false;
+ opt_propertyBag = opt_propertyBag || {};
+
+ // If a bubble is currently being shown, hide it.
+ this.hideBubble();
+
+ // Find the currently visible root-level page.
+ let rootPage = null;
+ for (const name in this.registeredPages) {
+ const page = this.registeredPages[name];
+ if (page.visible && !page.parentPage) {
+ rootPage = page;
+ break;
+ }
+ }
+
+ // Find the target page.
+ let targetPage = this.registeredPages[pageName.toLowerCase()];
+ if (!targetPage || !targetPage.canShowPage()) {
+ // If it's not a page, try it as an overlay.
+ const hash = opt_propertyBag.hash || '';
+ if (!targetPage && this.showOverlay_(pageName, hash, rootPage)) {
+ if (opt_updateHistory) {
+ this.updateHistoryState_(!!opt_propertyBag.replaceState);
+ }
+ this.updateTitle_();
+ return;
+ }
+ targetPage = this.defaultPage_;
+ }
+
+ pageName = targetPage.name.toLowerCase();
+ const targetPageWasVisible = targetPage.visible;
+
+ // Determine if the root page is 'sticky', meaning that it
+ // shouldn't change when showing an overlay. This can happen for special
+ // pages like Search.
+ const isRootPageLocked =
+ rootPage && rootPage.sticky && targetPage.parentPage;
+
+ // Notify pages if they will be hidden.
+ this.forEachPage_(!isRootPageLocked, function(page) {
+ if (page.name != pageName && !this.isAncestorOfPage(page, targetPage)) {
+ page.willHidePage();
+ }
+ });
+
+ // Update the page's hash.
+ targetPage.hash = opt_propertyBag.hash || '';
+
+ // Update visibilities to show only the hierarchy of the target page.
+ this.forEachPage_(!isRootPageLocked, function(page) {
+ page.visible =
+ page.name == pageName || this.isAncestorOfPage(page, targetPage);
+ });
+
+ // Update the history and current location.
+ if (opt_updateHistory) {
+ this.updateHistoryState_(!!opt_propertyBag.replaceState);
+ }
+
+ // Update focus if any other control was focused on the previous page,
+ // or the previous page is not known.
+ if (document.activeElement != document.body &&
+ (!rootPage || rootPage.pageDiv.contains(document.activeElement))) {
+ targetPage.focus();
+ }
+
+ // Notify pages if they were shown.
+ this.forEachPage_(!isRootPageLocked, function(page) {
+ if (!targetPageWasVisible &&
+ (page.name == pageName ||
+ this.isAncestorOfPage(page, targetPage))) {
+ page.didShowPage();
+ }
+ });
+
+ // If the target page was already visible, notify it that its hash
+ // changed externally.
+ if (targetPageWasVisible) {
+ targetPage.didChangeHash();
+ }
+
+ // Update the document title. Do this after didShowPage was called, in
+ // case a page decides to change its title.
+ this.updateTitle_();
+ },
+
+ /**
+ * Returns the name of the page from the current path.
+ * @return {string} Name of the page specified by the current path.
+ */
+ getPageNameFromPath: function() {
+ const path = location.pathname;
+ if (path.length <= 1) {
+ return this.defaultPage_.name;
+ }
+
+ // Skip starting slash and remove trailing slash (if any).
+ return path.slice(1).replace(/\/$/, '');
+ },
+
+ /**
+ * Gets the level of the page. Root pages (e.g., BrowserOptions) are at
+ * level 0.
+ * @return {number} How far down this page is from the root page.
+ */
+ getNestingLevel: function(page) {
+ let level = 0;
+ let parent = page.parentPage;
+ while (parent) {
+ level++;
+ parent = parent.parentPage;
+ }
+ return level;
+ },
+
+ /**
+ * Checks whether one page is an ancestor of the other page in terms of
+ * subpage nesting.
+ * @param {cr.ui.pageManager.Page} potentialAncestor Potential ancestor.
+ * @param {cr.ui.pageManager.Page} potentialDescendent Potential descendent.
+ * @return {boolean} True if |potentialDescendent| is nested under
+ * |potentialAncestor|.
+ */
+ isAncestorOfPage: function(potentialAncestor, potentialDescendent) {
+ let parent = potentialDescendent.parentPage;
+ while (parent) {
+ if (parent == potentialAncestor) {
+ return true;
+ }
+ parent = parent.parentPage;
+ }
+ return false;
+ },
+
+ /**
+ * Returns true if the page is a direct descendent of a root page, or if
+ * the page is considered always on top. Doesn't consider visibility.
+ * @param {cr.ui.pageManager.Page} page Page to check.
+ * @return {boolean} True if |page| is a top-level overlay.
+ */
+ isTopLevelOverlay: function(page) {
+ return page.isOverlay &&
+ (page.alwaysOnTop || this.getNestingLevel(page) == 1);
+ },
+
+ /**
+ * Called when an page is shown or hidden to update the root page
+ * based on the page's new visibility.
+ * @param {cr.ui.pageManager.Page} page The page being made visible or
+ * invisible.
+ */
+ onPageVisibilityChanged: function(page) {
+ this.updateRootPageFreezeState();
+
+ for (let i = 0; i < this.observers_.length; ++i) {
+ this.observers_[i].onPageVisibilityChanged(page);
+ }
+
+ if (!page.visible && this.isTopLevelOverlay(page)) {
+ this.updateScrollPosition_();
+ }
+ },
+
+ /**
+ * Called when a page's hash changes. If the page is the topmost visible
+ * page, the history state is updated.
+ * @param {cr.ui.pageManager.Page} page The page whose hash has changed.
+ */
+ onPageHashChanged: function(page) {
+ if (page == this.getTopmostVisiblePage()) {
+ this.updateHistoryState_(false);
+ }
+ },
+
+ /**
+ * Returns the topmost visible page, or null if no page is visible.
+ * @return {cr.ui.pageManager.Page} The topmost visible page.
+ */
+ getTopmostVisiblePage: function() {
+ // Check overlays first since they're top-most if visible.
+ return this.getVisibleOverlay_() ||
+ this.getTopmostVisibleNonOverlayPage_();
+ },
+
+ /**
+ * Closes the visible overlay. Updates the history state after closing the
+ * overlay.
+ */
+ closeOverlay: function() {
+ const overlay = this.getVisibleOverlay_();
+ if (!overlay) {
+ return;
+ }
+
+ overlay.visible = false;
+ overlay.didClosePage();
+
+ this.updateHistoryState_(false);
+ this.updateTitle_();
+
+ this.restoreLastFocusedElement_();
+ },
+
+ /**
+ * Closes all overlays and updates the history after each closed overlay.
+ */
+ closeAllOverlays: function() {
+ while (this.isOverlayVisible_()) {
+ this.closeOverlay();
+ }
+ },
+
+ /**
+ * Cancels (closes) the overlay, due to the user pressing <Esc>.
+ */
+ cancelOverlay: function() {
+ // Blur the active element to ensure any changed pref value is saved.
+ document.activeElement.blur();
+ const overlay = this.getVisibleOverlay_();
+ if (!overlay) {
+ return;
+ }
+ // Let the overlay handle the <Esc> if it wants to.
+ if (overlay.handleCancel) {
+ overlay.handleCancel();
+ this.restoreLastFocusedElement_();
+ } else {
+ this.closeOverlay();
+ }
+ },
+
+ /**
+ * Shows an informational bubble displaying |content| and pointing at the
+ * |target| element. If |content| has focusable elements, they join the
+ * current page's tab order as siblings of |domSibling|.
+ * @param {HTMLDivElement} content The content of the bubble.
+ * @param {HTMLElement} target The element at which the bubble points.
+ * @param {HTMLElement} domSibling The element after which the bubble is
+ * added to the DOM.
+ * @param {cr.ui.ArrowLocation} location The arrow location.
+ */
+ showBubble: function(content, target, domSibling, location) {
+ this.hideBubble();
+
+ const bubble = new cr.ui.AutoCloseBubble;
+ bubble.anchorNode = target;
+ bubble.domSibling = domSibling;
+ bubble.arrowLocation = location;
+ bubble.content = content;
+ bubble.show();
+ this.bubble_ = bubble;
+ },
+
+ /**
+ * Hides the currently visible bubble, if any.
+ */
+ hideBubble: function() {
+ if (this.bubble_) {
+ this.bubble_.hide();
+ }
+ },
+
+ /**
+ * Returns the currently visible bubble, or null if no bubble is visible.
+ * @return {cr.ui.AutoCloseBubble} The bubble currently being shown.
+ */
+ getVisibleBubble: function() {
+ const bubble = this.bubble_;
+ return bubble && !bubble.hidden ? bubble : null;
+ },
+
+ /**
+ * Callback for window.onpopstate to handle back/forward navigations.
+ * @param {string} pageName The current page name.
+ * @param {string} hash The hash to pass into the page.
+ * @param {Object} data State data pushed into history.
+ */
+ setState: function(pageName, hash, data) {
+ const currentOverlay = this.getVisibleOverlay_();
+ const lowercaseName = pageName.toLowerCase();
+ const newPage = this.registeredPages[lowercaseName] ||
+ this.registeredOverlayPages[lowercaseName] || this.defaultPage_;
+ if (currentOverlay && !this.isAncestorOfPage(currentOverlay, newPage)) {
+ currentOverlay.visible = false;
+ currentOverlay.didClosePage();
+ }
+ this.showPageByName(pageName, false, {hash: hash});
+ },
+
+
+ /**
+ * Whether the page is still loading (i.e. onload hasn't finished running).
+ * @return {boolean} Whether the page is still loading.
+ */
+ isLoading: function() {
+ return document.documentElement.classList.contains('loading');
+ },
+
+ /**
+ * Callback for window.onbeforeunload. Used to notify overlays that they
+ * will be closed.
+ */
+ willClose: function() {
+ const overlay = this.getVisibleOverlay_();
+ if (overlay) {
+ overlay.didClosePage();
+ }
+ },
+
+ /**
+ * Freezes/unfreezes the scroll position of the root page based on the
+ * current page stack.
+ */
+ updateRootPageFreezeState: function() {
+ const topPage = this.getTopmostVisiblePage();
+ if (topPage) {
+ this.setRootPageFrozen_(topPage.isOverlay);
+ }
+ },
+
+ /**
+ * Change the horizontal offset used to reposition elements while showing an
+ * overlay from the default.
+ */
+ set horizontalOffset(value) {
+ this.horizontalOffset_ = value;
+ },
+
+ /**
+ * @param {!cr.ui.pageManager.PageManager.Observer} observer The observer to
+ * register.
+ */
+ addObserver: function(observer) {
+ this.observers_.push(observer);
+ },
+
+ /**
+ * Shows a registered overlay page. Does not update history.
+ * @param {string} overlayName Page name.
+ * @param {string} hash The hash state to associate with the overlay.
+ * @param {cr.ui.pageManager.Page} rootPage The currently visible root-level
+ * page.
+ * @return {boolean} Whether we showed an overlay.
+ * @private
+ */
+ showOverlay_: function(overlayName, hash, rootPage) {
+ const overlay = this.registeredOverlayPages[overlayName.toLowerCase()];
+ if (!overlay || !overlay.canShowPage()) {
+ return false;
+ }
+
+ const focusOutlineManager =
+ cr.ui.FocusOutlineManager.forDocument(document);
+
+ // Save the currently focused element in the page for restoration later.
+ const currentPage = this.getTopmostVisiblePage();
+ if (currentPage && focusOutlineManager.visible) {
+ currentPage.lastFocusedElement = document.activeElement;
+ }
+
+ if ((!rootPage || !rootPage.sticky) && overlay.parentPage &&
+ !overlay.parentPage.visible) {
+ this.showPageByName(overlay.parentPage.name, false);
+ }
+
+ overlay.hash = hash;
+ if (!overlay.visible) {
+ overlay.visible = true;
+ overlay.didShowPage();
+ } else {
+ overlay.didChangeHash();
+ }
+
+ if (focusOutlineManager.visible) {
+ overlay.focus();
+ }
+
+ if (!overlay.pageDiv.contains(document.activeElement)) {
+ document.activeElement.blur();
+ }
+
+ if ($('search-field') && $('search-field').value == '') {
+ const section = overlay.associatedSection;
+ if (section) {
+ /** @suppress {checkTypes|checkVars} */
+ (function() {
+ options.BrowserOptions.scrollToSection(section);
+ })();
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns whether or not an overlay is visible.
+ * @return {boolean} True if an overlay is visible.
+ * @private
+ */
+ isOverlayVisible_: function() {
+ return this.getVisibleOverlay_() != null;
+ },
+
+ /**
+ * Returns the currently visible overlay, or null if no page is visible.
+ * @return {cr.ui.pageManager.Page} The visible overlay.
+ * @private
+ */
+ getVisibleOverlay_: function() {
+ let topmostPage = null;
+ for (const name in this.registeredOverlayPages) {
+ const page = this.registeredOverlayPages[name];
+ if (!page.visible) {
+ continue;
+ }
+
+ if (page.alwaysOnTop) {
+ return page;
+ }
+
+ if (!topmostPage ||
+ this.getNestingLevel(page) > this.getNestingLevel(topmostPage)) {
+ topmostPage = page;
+ }
+ }
+ return topmostPage;
+ },
+
+ /**
+ * Returns the topmost visible page (overlays excluded).
+ * @return {cr.ui.pageManager.Page} The topmost visible page aside from any
+ * overlays.
+ * @private
+ */
+ getTopmostVisibleNonOverlayPage_: function() {
+ for (const name in this.registeredPages) {
+ const page = this.registeredPages[name];
+ if (page.visible) {
+ return page;
+ }
+ }
+
+ return null;
+ },
+
+ /**
+ * Scrolls the page to the correct position (the top when opening an
+ * overlay, or the old scroll position a previously hidden overlay
+ * becomes visible).
+ * @private
+ */
+ updateScrollPosition_: function() {
+ const container = $('page-container');
+ const scrollTop = container.oldScrollTop || 0;
+ container.oldScrollTop = undefined;
+ window.scroll(scrollLeftForDocument(document), scrollTop);
+ },
+
+ /**
+ * Updates the title to the title of the current page, or of the topmost
+ * visible page with a non-empty title.
+ * @private
+ */
+ updateTitle_: function() {
+ let page = this.getTopmostVisiblePage();
+ while (page) {
+ if (page.title) {
+ for (let i = 0; i < this.observers_.length; ++i) {
+ this.observers_[i].updateTitle(page.title);
+ }
+ return;
+ }
+ page = page.parentPage;
+ }
+ },
+
+ /**
+ * Constructs a new path to push onto the history stack, using observers
+ * to update the history.
+ * @param {boolean} replace If true, handlers should replace the current
+ * history event rather than create new ones.
+ * @private
+ */
+ updateHistoryState_: function(replace) {
+ if (this.isDialog) {
+ return;
+ }
+
+ const page = this.getTopmostVisiblePage();
+ let path = window.location.pathname + window.location.hash;
+ if (path) {
+ // Remove trailing slash.
+ path = path.slice(1).replace(/\/(?:#|$)/, '');
+ }
+
+ // If the page is already in history (the user may have clicked the same
+ // link twice, or this is the initial load), do nothing.
+ const newPath = (page == this.defaultPage_ ? '' : page.name) + page.hash;
+ if (path == newPath) {
+ return;
+ }
+
+ for (let i = 0; i < this.observers_.length; ++i) {
+ this.observers_[i].updateHistory(newPath, replace);
+ }
+ },
+
+ /**
+ * Restores the last focused element on a given page.
+ * @private
+ */
+ restoreLastFocusedElement_: function() {
+ const currentPage = this.getTopmostVisiblePage();
+
+ if (!currentPage.lastFocusedElement) {
+ return;
+ }
+
+ if (cr.ui.FocusOutlineManager.forDocument(document).visible) {
+ currentPage.lastFocusedElement.focus();
+ }
+
+ currentPage.lastFocusedElement = null;
+ },
+
+ /**
+ * Find an enclosing section for an element if it exists.
+ * @param {Node} node Element to search.
+ * @return {Node} The section element, or null.
+ * @private
+ */
+ findSectionForNode_: function(node) {
+ while (node = node.parentNode) {
+ if (node.nodeName == 'SECTION') {
+ return node;
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Freezes/unfreezes the scroll position of the root page container.
+ * @param {boolean} freeze Whether the page should be frozen.
+ * @private
+ */
+ setRootPageFrozen_: function(freeze) {
+ const container = $('page-container');
+ if (container.classList.contains('frozen') == freeze) {
+ return;
+ }
+
+ if (freeze) {
+ // Lock the width, since auto width computation may change.
+ container.style.width = window.getComputedStyle(container).width;
+ container.oldScrollTop = scrollTopForDocument(document);
+ container.classList.add('frozen');
+ const verticalPosition =
+ container.getBoundingClientRect().top - container.oldScrollTop;
+ container.style.top = verticalPosition + 'px';
+ this.updateFrozenElementHorizontalPosition_(container);
+ } else {
+ container.classList.remove('frozen');
+ container.style.top = '';
+ container.style.left = '';
+ container.style.right = '';
+ container.style.width = '';
+ }
+ },
+
+ /**
+ * Called when the page is scrolled; moves elements that are position:fixed
+ * but should only behave as if they are fixed for vertical scrolling.
+ * @private
+ */
+ handleScroll_: function() {
+ this.updateAllFrozenElementPositions_();
+ },
+
+ /**
+ * Updates all frozen pages to match the horizontal scroll position.
+ * @private
+ */
+ updateAllFrozenElementPositions_: function() {
+ const frozenElements = document.querySelectorAll('.frozen');
+ for (let i = 0; i < frozenElements.length; i++) {
+ this.updateFrozenElementHorizontalPosition_(frozenElements[i]);
+ }
+ },
+
+ /**
+ * Updates the given frozen element to match the horizontal scroll position.
+ * @param {HTMLElement} e The frozen element to update.
+ * @private
+ */
+ updateFrozenElementHorizontalPosition_: function(e) {
+ if (isRTL()) {
+ e.style.right = this.horizontalOffset + 'px';
+ } else {
+ const scrollLeft = scrollLeftForDocument(document);
+ e.style.left = this.horizontalOffset - scrollLeft + 'px';
+ }
+ },
+
+ /**
+ * Calls the given callback with each registered page.
+ * @param {boolean} includeRootPages Whether the callback should be called
+ * for the root pages.
+ * @param {function(cr.ui.pageManager.Page)} callback The callback.
+ * @private
+ */
+ forEachPage_: function(includeRootPages, callback) {
+ let pageNames = Object.keys(this.registeredOverlayPages);
+ if (includeRootPages) {
+ pageNames = Object.keys(this.registeredPages).concat(pageNames);
+ }
+
+ pageNames.forEach(function(name) {
+ callback.call(
+ this,
+ this.registeredOverlayPages[name] || this.registeredPages[name]);
+ }, this);
+ },
+ };
+
+ /**
+ * An observer of PageManager.
+ * @constructor
+ */
+ PageManager.Observer = function() {};
+
+ PageManager.Observer.prototype = {
+ /**
+ * Called when a page is being shown or has been hidden.
+ * @param {cr.ui.pageManager.Page} page The page being shown or hidden.
+ */
+ onPageVisibilityChanged: function(page) {},
+
+ /**
+ * Called when a new title should be set.
+ * @param {string} title The title to set.
+ */
+ updateTitle: function(title) {},
+
+ /**
+ * Called when a page is navigated to.
+ * @param {string} path The path of the page being visited.
+ * @param {boolean} replace If true, allow no history events to be created.
+ */
+ updateHistory: function(path, replace) {},
+ };
+
+ // Export
+ return {PageManager: PageManager};
+});
diff --git a/chromium/chrome/browser/resources/bluetooth_internals/resources.grd b/chromium/chrome/browser/resources/bluetooth_internals/resources.grd
index 786dc15be70..4cd5644cc98 100644
--- a/chromium/chrome/browser/resources/bluetooth_internals/resources.grd
+++ b/chromium/chrome/browser/resources/bluetooth_internals/resources.grd
@@ -29,6 +29,10 @@
file="adapter_page.js"
type="BINDATA"
compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_DEBUG_LOG_PAGE_JS"
+ file="debug_log_page.js"
+ type="BINDATA"
+ compress="gzip" />
<include name="IDR_BLUETOOTH_INTERNALS_CHARACTERISTIC_LIST_JS"
file="characteristic_list.js"
type="BINDATA"
@@ -89,6 +93,23 @@
file="object_fieldset.js"
type="BINDATA"
compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_PAGE_MANAGER_HTML"
+ file="page_manager.html"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_PAGE_MANAGER_JS"
+ file="page_manager.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_PAGE_HTML"
+ file="page.html"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_BLUETOOTH_INTERNALS_PAGE_JS"
+ file="page.js"
+ type="BINDATA"
+ compress="gzip" />
+
<include name="IDR_BLUETOOTH_INTERNALS_SERVICE_LIST_JS"
file="service_list.js"
type="BINDATA"
diff --git a/chromium/chrome/browser/resources/bookmarks/README.md b/chromium/chrome/browser/resources/bookmarks/README.md
index c6c83b16d7f..272a91dad29 100644
--- a/chromium/chrome/browser/resources/bookmarks/README.md
+++ b/chromium/chrome/browser/resources/bookmarks/README.md
@@ -23,11 +23,11 @@ of the code:
and between two different BMM instances from different Chrome profiles.
* **Policy support**: Several policies are respected:
- - [EditBookmarksEnabled](https://www.chromium.org/administrators/policy-list-3#EditBookmarksEnabled):
+ - [EditBookmarksEnabled](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=EditBookmarksEnabled):
Prevents all editing operations
- - [ManagedBookmarks](https://www.chromium.org/administrators/policy-list-3#ManagedBookmarks):
+ - [ManagedBookmarks](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ManagedBookmarks):
Defines a folder of immutable bookmarks.
- - [IncognitoModeAvailability](https://www.chromium.org/administrators/policy-list-3#IncognitoModeAvailability):
+ - [IncognitoModeAvailability](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=IncognitoModeAvailability):
Disables/force-enables opening bookmarks in Incognito
## Data-flow model
diff --git a/chromium/chrome/browser/resources/bookmarks/command_manager.html b/chromium/chrome/browser/resources/bookmarks/command_manager.html
index a2e14d04d4e..aa5a6854590 100644
--- a/chromium/chrome/browser/resources/bookmarks/command_manager.html
+++ b/chromium/chrome/browser/resources/bookmarks/command_manager.html
@@ -37,7 +37,7 @@
<button class="dropdown-item"
command$="[[command]]"
hidden$="[[!isCommandVisible_(command, menuIds_)]]"
- disabled$="[[!isCommandEnabled_(command, menuIds_)]]"
+ disabled$="[[!isCommandEnabled_(command, menuIds_, canPaste_)]]"
on-click="onCommandClick_">
<span class="label">
[[getCommandLabel_(command, menuIds_)]]
diff --git a/chromium/chrome/browser/resources/bookmarks/command_manager.js b/chromium/chrome/browser/resources/bookmarks/command_manager.js
index 3d83ab732f6..eb2408d17a2 100644
--- a/chromium/chrome/browser/resources/bookmarks/command_manager.js
+++ b/chromium/chrome/browser/resources/bookmarks/command_manager.js
@@ -43,6 +43,9 @@ cr.define('bookmarks', function() {
},
/** @private */
+ canPaste_: Boolean,
+
+ /** @private */
globalCanEdit_: Boolean,
},
@@ -53,9 +56,7 @@ cr.define('bookmarks', function() {
assert(CommandManager.instance_ == null);
CommandManager.instance_ = this;
- this.watch('globalCanEdit_', function(state) {
- return state.prefs.canEdit;
- });
+ this.watch('globalCanEdit_', state => state.prefs.canEdit);
this.updateFromStore();
/** @private {!Map<Command, cr.ui.KeyboardShortcutList>} */
@@ -214,8 +215,9 @@ cr.define('bookmarks', function() {
isCommandVisible_: function(command, itemIds) {
switch (command) {
case Command.EDIT:
- case Command.PASTE:
return itemIds.size == 1 && this.globalCanEdit_;
+ case Command.PASTE:
+ return this.globalCanEdit_;
case Command.CUT:
case Command.COPY:
return itemIds.size >= 1 && this.globalCanEdit_;
@@ -274,7 +276,7 @@ cr.define('bookmarks', function() {
case Command.IMPORT:
return this.globalCanEdit_;
case Command.PASTE:
- return true; // TODO(hcarmona): Add check for CanPasteFromClipboard.
+ return this.canPaste_;
default:
return true;
}
@@ -800,6 +802,19 @@ cr.define('bookmarks', function() {
cr.toastManager.getInstance().showForStringPieces(pieces, canUndo);
},
+ /**
+ * @param {number} targetId
+ * @private
+ */
+ updateCanPaste_: function(targetId) {
+ return new Promise(resolve => {
+ chrome.bookmarkManagerPrivate.canPaste(`${targetId}`, result => {
+ this.canPaste_ = result;
+ resolve();
+ });
+ });
+ },
+
////////////////////////////////////////////////////////////////////////////
// Event handlers:
@@ -807,7 +822,8 @@ cr.define('bookmarks', function() {
* @param {Event} e
* @private
*/
- onOpenCommandMenu_: function(e) {
+ onOpenCommandMenu_: async function(e) {
+ await this.updateCanPaste_(e.detail.source);
if (e.detail.targetElement) {
this.openCommandMenuAtElement(e.detail.targetElement, e.detail.source);
} else {
diff --git a/chromium/chrome/browser/resources/bookmarks/shared_style.html b/chromium/chrome/browser/resources/bookmarks/shared_style.html
index 723f2db2e60..12b92904a9e 100644
--- a/chromium/chrome/browser/resources/bookmarks/shared_style.html
+++ b/chromium/chrome/browser/resources/bookmarks/shared_style.html
@@ -61,7 +61,7 @@
width: 20px;
}
-<if expr="is_macosx or is_ios">
+<if expr="is_macosx">
@media (prefers-color-scheme: dark) {
.folder-icon {
content: url(chrome://theme/IDR_FOLDER_CLOSED_WHITE);
@@ -69,7 +69,7 @@
}
</if>
-<if expr="not is_macosx and not is_ios">
+<if expr="not is_macosx">
.folder-icon[open] {
content: url(chrome://theme/IDR_FOLDER_OPEN);
}
diff --git a/chromium/chrome/browser/resources/browser_switch/BUILD.gn b/chromium/chrome/browser/resources/browser_switch/BUILD.gn
index 17c4dc37f59..7b25cc542d0 100644
--- a/chromium/chrome/browser/resources/browser_switch/BUILD.gn
+++ b/chromium/chrome/browser/resources/browser_switch/BUILD.gn
@@ -3,8 +3,10 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
deps = [
":app",
":browser_switch_proxy",
@@ -14,13 +16,20 @@ js_type_check("closure_compile") {
js_library("app") {
deps = [
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:i18n_behavior",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:i18n_behavior.m",
+ "//ui/webui/resources/js:load_time_data.m",
]
}
js_library("browser_switch_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
}
+
+polymer_modulizer("app") {
+ js_file = "app.js"
+ html_file = "app.html"
+ html_type = "v3-ready"
+}
diff --git a/chromium/chrome/browser/resources/browser_switch/app.html b/chromium/chrome/browser/resources/browser_switch/app.html
index 93b4c21d693..69890063617 100644
--- a/chromium/chrome/browser/resources/browser_switch/app.html
+++ b/chromium/chrome/browser/resources/browser_switch/app.html
@@ -1,43 +1,31 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style>
+ :host {
+ @apply --cr-card-elevation;
+ background-color: var(--cr-card-background-color);
+ border-radius: var(--cr-card-border-radius);
+ display: block;
+ margin: 16px;
+ max-width: 640px;
+ min-width: 500px;
+ padding: 16px;
+ }
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="browser_switch_proxy.html">
+ h1 {
+ color: var(--cr-primary-text-color);
+ font-size: 1rem;
+ font-weight: 500;
+ margin: 0;
+ padding: 0 0 14px 0;
+ }
-<dom-module id="browser-switch-app">
- <template>
- <style>
- :host {
- @apply --cr-card-elevation;
- background-color: var(--cr-card-background-color);
- border-radius: var(--cr-card-border-radius);
- display: block;
- margin: 16px;
- max-width: 640px;
- min-width: 500px;
- padding: 16px;
- }
+ p {
+ color: var(--cr-primary-text-color);
+ /* Should be 13px when html font-size is 16px */
+ font-size: 0.8125rem;
+ margin: 0;
+ max-width: 450px;
+ }
+</style>
- h1 {
- color: var(--cr-primary-text-color);
- font-size: 1rem;
- font-weight: 500;
- margin: 0;
- padding: 0 0 14px 0;
- }
-
- p {
- color: var(--cr-primary-text-color);
- /* Should be 13px when html font-size is 16px */
- font-size: 0.8125rem;
- margin: 0;
- max-width: 450px;
- }
- </style>
-
- <h1>[[computeTitle_(error_, secondCounter_)]]</h1>
- <p inner-h-t-m-l="[[computeDescription_(url_, error_)]]"></p>
- </template>
- <script src="app.js"></script>
-</dom-module>
+<h1>[[computeTitle_(error_, secondCounter_)]]</h1>
+<p inner-h-t-m-l="[[computeDescription_(url_, error_)]]"></p>
diff --git a/chromium/chrome/browser/resources/browser_switch/app.js b/chromium/chrome/browser/resources/browser_switch/app.js
index f8979c89826..6e4522ed222 100644
--- a/chromium/chrome/browser/resources/browser_switch/app.js
+++ b/chromium/chrome/browser/resources/browser_switch/app.js
@@ -2,9 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-'use strict';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import './strings.m.js';
-(function() {
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {BrowserSwitchProxyImpl} from './browser_switch_proxy.js';
/** @type {number} */
const MS_PER_SECOND = 1000;
@@ -18,6 +23,8 @@ const LaunchError = {
Polymer({
is: 'browser-switch-app',
+ _template: html`{__html_template__}`,
+
behaviors: [I18nBehavior],
properties: {
@@ -141,6 +148,5 @@ function getUrlHostname(url) {
}
function getProxy() {
- return browser_switch.BrowserSwitchProxyImpl.getInstance();
+ return BrowserSwitchProxyImpl.getInstance();
}
-})();
diff --git a/chromium/chrome/browser/resources/browser_switch/browser_switch.html b/chromium/chrome/browser/resources/browser_switch/browser_switch.html
index 968ae80f108..f987974dea6 100644
--- a/chromium/chrome/browser/resources/browser_switch/browser_switch.html
+++ b/chromium/chrome/browser/resources/browser_switch/browser_switch.html
@@ -25,9 +25,6 @@
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
-
- <link rel="import" href="chrome://resources/html/load_time_data.html">
- <script src="strings.js"></script>
- <link rel="import" href="app.html">
+ <script type="module" src="app.js"></script>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.html b/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.html
deleted file mode 100644
index 4dd11cd933b..00000000000
--- a/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="browser_switch_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.js b/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.js
index dd35bff286e..0be32291879 100644
--- a/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.js
+++ b/chromium/chrome/browser/resources/browser_switch/browser_switch_proxy.js
@@ -2,36 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('browser_switch', function() {
- /** @interface */
- class BrowserSwitchProxy {
- /**
- * @param {string} url URL to open in alternative browser.
- * @return {Promise} A promise that can fail if unable to launch. It will
- * never resolve, because the tab closes if this succeeds.
- */
- launchAlternativeBrowserAndCloseTab(url) {}
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
- gotoNewTabPage() {}
- }
+/** @interface */
+export class BrowserSwitchProxy {
+ /**
+ * @param {string} url URL to open in alternative browser.
+ * @return {Promise} A promise that can fail if unable to launch. It will
+ * never resolve, because the tab closes if this succeeds.
+ */
+ launchAlternativeBrowserAndCloseTab(url) {}
- /** @implements {browser_switch.BrowserSwitchProxy} */
- class BrowserSwitchProxyImpl {
- /** @override */
- launchAlternativeBrowserAndCloseTab(url) {
- return cr.sendWithPromise('launchAlternativeBrowserAndCloseTab', url);
- }
+ gotoNewTabPage() {}
+}
- /** @override */
- gotoNewTabPage() {
- chrome.send('gotoNewTabPage');
- }
+/** @implements {BrowserSwitchProxy} */
+export class BrowserSwitchProxyImpl {
+ /** @override */
+ launchAlternativeBrowserAndCloseTab(url) {
+ return sendWithPromise('launchAlternativeBrowserAndCloseTab', url);
}
- cr.addSingletonGetter(BrowserSwitchProxyImpl);
+ /** @override */
+ gotoNewTabPage() {
+ chrome.send('gotoNewTabPage');
+ }
+}
- return {
- BrowserSwitchProxy: BrowserSwitchProxy,
- BrowserSwitchProxyImpl: BrowserSwitchProxyImpl
- };
-});
+addSingletonGetter(BrowserSwitchProxyImpl);
diff --git a/chromium/chrome/browser/resources/chromeos/BUILD.gn b/chromium/chrome/browser/resources/chromeos/BUILD.gn
index 6d5a60739fa..8de13aa3ad6 100644
--- a/chromium/chrome/browser/resources/chromeos/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/BUILD.gn
@@ -65,6 +65,7 @@ group("closure_compile") {
"bluetooth_pairing_dialog:closure_compile",
"braille_ime:closure_compile",
"camera/src/js:closure_compile",
+ "crostini_installer:closure_compile",
"internet_config_dialog:closure_compile",
"internet_detail_dialog:closure_compile",
"login:closure_compile",
diff --git a/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
index d41c627794d..ad8a9d9ac16 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -79,8 +79,9 @@ copy("chrome_camera_app_images") {
"src/images/camera_button_timer_on_10s.svg",
"src/images/camera_button_timer_on_3s.svg",
"src/images/camera_focus_aim.svg",
- "src/images/camera_intro_banner_close.svg",
- "src/images/camera_intro_banner_icon.svg",
+ "src/images/camera_intent_play_video.svg",
+ "src/images/camera_intent_result_cancel.svg",
+ "src/images/camera_intent_result_confirm.svg",
"src/images/camera_mode_photo.svg",
"src/images/camera_mode_portrait.svg",
"src/images/camera_mode_square.svg",
@@ -114,6 +115,7 @@ copy("chrome_camera_app_js") {
"src/js/background.js",
"src/js/gallerybutton.js",
"src/js/google-analytics-bundle.js",
+ "src/js/intent.js",
"src/js/main.js",
"src/js/metrics.js",
"src/js/nav.js",
@@ -146,6 +148,7 @@ copy("chrome_camera_app_js_device") {
"src/js/device/camera3_device_info.js",
"src/js/device/constraints_preferrer.js",
"src/js/device/device_info_updater.js",
+ "src/js/device/error.js",
]
outputs = [
@@ -155,11 +158,13 @@ copy("chrome_camera_app_js_device") {
copy("chrome_camera_app_js_models") {
sources = [
+ "src/js/models/file_video_saver.js",
"src/js/models/filenamer.js",
"src/js/models/filesystem.js",
"src/js/models/gallery.js",
+ "src/js/models/intent_video_saver.js",
"src/js/models/result_saver.js",
- "src/js/models/video_saver.js",
+ "src/js/models/video_saver_interface.js",
]
outputs = [
@@ -169,6 +174,7 @@ copy("chrome_camera_app_js_models") {
copy("chrome_camera_app_js_mojo") {
sources = [
+ "src/js/mojo/chrome_helper.js",
"src/js/mojo/device_operator.js",
"src/js/mojo/image_capture.js",
]
@@ -182,6 +188,7 @@ copy("chrome_camera_app_js_views") {
sources = [
"src/js/views/browser.js",
"src/js/views/camera.js",
+ "src/js/views/camera_intent.js",
"src/js/views/dialog.js",
"src/js/views/gallery_base.js",
"src/js/views/settings.js",
@@ -201,6 +208,7 @@ copy("chrome_camera_app_js_views_camera") {
"src/js/views/camera/options.js",
"src/js/views/camera/preview.js",
"src/js/views/camera/recordtime.js",
+ "src/js/views/camera/review_result.js",
"src/js/views/camera/timertick.js",
]
@@ -214,7 +222,9 @@ copy("chrome_camera_app_sounds") {
"src/sounds/record_end.ogg",
"src/sounds/record_start.ogg",
"src/sounds/shutter.ogg",
- "src/sounds/tick.ogg",
+ "src/sounds/tick_final.ogg",
+ "src/sounds/tick_inc.ogg",
+ "src/sounds/tick_start.ogg",
]
outputs = [
@@ -234,6 +244,8 @@ copy("chrome_camera_app_views") {
copy("chrome_camera_app_mojo_generated") {
sources = [
+ "$root_gen_dir/components/arc/mojom/camera_intent.mojom-lite.js",
+ "$root_gen_dir/components/chromeos_camera/common/camera_app_helper.mojom-lite.js",
"$root_gen_dir/media/capture/mojom/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",
@@ -245,6 +257,9 @@ copy("chrome_camera_app_mojo_generated") {
]
deps = [
+ "//components/arc/mojom:camera_intent_js",
+ "//components/arc/mojom:mojom_js",
+ "//components/chromeos_camera/common:camera_app_helper_js",
"//media/capture/mojom:image_capture_js",
"//media/capture/video/chromeos/mojom:cros_camera_js",
"//mojo/public/js:bindings_lite",
diff --git a/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd b/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
index 0a9ac124ab1..5db7aa1386c 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
+++ b/chromium/chrome/browser/resources/chromeos/camera/camera_resources.grd
@@ -17,16 +17,20 @@
<structure name="IDR_CAMERA_BUNDLE_JS" file="src/js/google-analytics-bundle.js" type="chrome_html" />
<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_CAMERA_INTENT_JS" file="src/js/views/camera_intent.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_CHROME_HELPER_JS" file="src/js/mojo/chrome_helper.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_ERROR_JS" file="src/js/device/error.js" type="chrome_html" />
<structure name="IDR_CAMERA_FILENAMER_JS" file="src/js/models/filenamer.js" type="chrome_html" />
<structure name="IDR_CAMERA_FILESYSTEM_JS" file="src/js/models/filesystem.js" type="chrome_html" />
<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/image_capture.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_INTENT_JS" file="src/js/intent.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" />
@@ -40,6 +44,7 @@
<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_REVIEW_RESULT_JS" file="src/js/views/camera/review_result.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" />
@@ -48,13 +53,19 @@
<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_VIDEO_SAVER_INTERFACE_JS" file="src/js/models/video_saver_interface.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_INTENT_VIDEO_SAVER_JS" file="src/js/models/file_video_saver.js" type="chrome_html" />
+ <structure name="IDR_CAMERA_FILE_VIDEO_SAVER_JS" file="src/js/models/intent_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" />
</structures>
<includes>
<!-- Mojo Lite Bindings -->
+ <include name="IDR_CAMERA_CAMERA_INTENT_MOJOM_LITE_JS"
+ file="${root_gen_dir}/components/arc/mojom/camera_intent.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"/>
<include name="IDR_CAMERA_IMAGE_CAPTURE_MOJOM_LITE_JS"
file="${root_gen_dir}/media/capture/mojom/image_capture.mojom-lite.js"
use_base_dir="false"
@@ -79,14 +90,15 @@
<include name="IDR_CAMERA_RECORD_END_OGG" file="src/sounds/record_end.ogg" type="BINDATA" />
<include name="IDR_CAMERA_RECORD_START_OGG" file="src/sounds/record_start.ogg" type="BINDATA" />
<include name="IDR_CAMERA_SHUTTER_OGG" file="src/sounds/shutter.ogg" type="BINDATA" />
- <include name="IDR_CAMERA_TICK_OGG" file="src/sounds/tick.ogg" type="BINDATA" />
+ <include name="IDR_CAMERA_TICK_FINAL_OGG" file="src/sounds/tick_final.ogg" type="BINDATA" />
+ <include name="IDR_CAMERA_TICK_INC_OGG" file="src/sounds/tick_inc.ogg" type="BINDATA" />
+ <include name="IDR_CAMERA_TICK_START_OGG" file="src/sounds/tick_start.ogg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_SQUARE_SVG" file="src/images/camera_mode_square.svg" type="BINDATA" />
<include name="IDR_CAMERA_SETTINGS_BUTTON_BACK_SVG" file="src/images/settings_button_back.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_MODE_PORTRAIT_SVG" file="src/images/camera_mode_portrait.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_TIMER_ON_3S_SVG" file="src/images/camera_button_timer_on_3s.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_VIDEO_START_HOVER_SVG" file="src/images/camera_shutter_video_start_hover.svg" type="BINDATA" />
<include name="IDR_CAMERA_SPINNER_SVG" file="src/images/spinner.svg" type="BINDATA" />
- <include name="IDR_CAMERA_CAMERA_INTRO_BANNER_ICON_SVG" file="src/images/camera_intro_banner_icon.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_GRID_OFF_SVG" file="src/images/camera_button_grid_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIC_ON_SVG" file="src/images/camera_button_mic_on.svg" type="BINDATA" />
<include name="IDR_CAMERA_BROWSER_BUTTON_DELETE_SVG" file="src/images/browser_button_delete.svg" type="BINDATA" />
@@ -110,7 +122,6 @@
<include name="IDR_CAMERA_SETTINGS_GRID_TYPE_SVG" file="src/images/settings_grid_type.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_BUTTON_MIRROR_OFF_SVG" file="src/images/camera_button_mirror_off.svg" type="BINDATA" />
<include name="IDR_CAMERA_BROWSER_BUTTON_EXPORT_SVG" file="src/images/browser_button_export.svg" type="BINDATA" />
- <include name="IDR_CAMERA_CAMERA_INTRO_BANNER_CLOSE_SVG" file="src/images/camera_intro_banner_close.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_PHOTO_START_SVG" file="src/images/camera_shutter_photo_start.svg" type="BINDATA" />
<include name="IDR_CAMERA_BROWSER_BUTTON_BACK_SVG" file="src/images/browser_button_back.svg" type="BINDATA" />
<include name="IDR_CAMERA_CAMERA_SHUTTER_VIDEO_STOP_SVG" file="src/images/camera_shutter_video_stop.svg" 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 cf3600060c5..3a824bee776 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
@@ -95,6 +95,14 @@
"message": "Grid type",
"description": "Label for the button of grid-type options."
},
+ "LABEL_30FPS": {
+ "message": "30 FPS",
+ "description": "Label showing current state of 30 FPS on tooltip of toggle 60 FPS recording checkbox."
+ },
+ "LABEL_60FPS": {
+ "message": "60 FPS",
+ "description": "Label showing current state of 60 FPS on tooltip of toggle 60 FPS recording checkbox."
+ },
"TOGGLE_60FPS_BUTTON": {
"message": "60 FPS",
"description": "Label for the checkbox to toggle 60 FPS recording."
@@ -333,20 +341,16 @@
"message": "Photos and videos taken with the camera will be moved to the Downloads folder. You can access them in Files.\n\nApps with storage permissions will have access to your photos and videos.",
"description": "Message shown before moving all photos and videos stored in the Camera App to the Downloads folder."
},
- "BANNER_TITLE": {
- "message": "A whole new look",
- "description": "Title of banner shown for introducing new camera App UI."
+ "CONFIRM_REVIEW_BUTTON": {
+ "message": "Confirm",
+ "description": "Label for the confirm button to confirm with the reviewed photo or video."
},
- "BANNER_MSG": {
- "message": "Your camera now supports new modes and your photos and videos will be available under your Downloads folders.",
- "description": "Message in the banner shown for introducing new camera App UI."
- },
- "BANNER_CLOSE_BUTTON": {
- "message": "Close",
- "description": "Label for close introducing new camera App UI banner button."
+ "CANCEL_REVIEW_BUTTON": {
+ "message": "Cancel",
+ "description": "Label for the cancel button to cancel with the reviewed photo or video."
},
- "BANNER_LEARN_MORE_BUTTON": {
- "message": "Learn more",
- "description": "Label for learn more about new camera App UI button."
+ "PLAY_RESULT_VIDEO_BUTTON": {
+ "message": "Play video",
+ "description": "Label for the button to play video."
}
} \ No newline at end of file
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 059505eb02c..7ea176a9a3f 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/BUILD.gn
@@ -17,6 +17,9 @@ group("closure_compile") {
js_type_check("compile_resources") {
deps = [
+ ":background",
+ ":intent",
+ ":metrics",
":nav",
":resolution_event_broker",
":state",
@@ -26,6 +29,18 @@ js_type_check("compile_resources") {
]
}
+js_library("intent") {
+ deps = [
+ "mojo:chrome_helper",
+ ]
+}
+
+js_library("metrics") {
+ deps = [
+ "externs:chrome_platform_analytics",
+ ]
+}
+
js_library("resolution_event_broker") {
}
@@ -39,6 +54,12 @@ js_library("nav") {
js_library("state") {
}
+js_library("background") {
+ deps = [
+ ":intent",
+ ]
+}
+
js_library("toast") {
deps = [
":util",
@@ -52,6 +73,7 @@ js_library("util") {
deps = [
":tooltip",
"browser_proxy:browser_proxy",
+ "mojo:chrome_helper",
]
externs_list = [ "$externs_path/chrome_extensions.js" ]
}
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 cc01ba9b370..a54df9607b7 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
@@ -9,6 +9,7 @@ js_type_check("closure_compile") {
":camera3_device_info",
":constraints_preferrer",
":device_info_updater",
+ ":error",
]
}
@@ -31,6 +32,10 @@ js_library("device_info_updater") {
deps = [
":camera3_device_info",
":constraints_preferrer",
+ ":error",
"..:state",
]
}
+
+js_library("error") {
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/externs/BUILD.gn
index b542932ff9c..e41499011b1 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/externs/BUILD.gn
@@ -4,11 +4,8 @@
import("//third_party/closure_compiler/compile_js.gni")
-js_type_check("closure_compile") {
- deps = [
- ":viewer-pen-options",
- ]
-}
+js_library("chrome_platform_analytics") {
+ sources = []
-js_library("viewer-pen-options") {
+ externs_list = [ "chrome_platform_analytics.js" ]
}
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 db0f77e3e3f..39e60221b1d 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
@@ -33,4 +33,12 @@ js_library("result_saver") {
}
js_library("video_saver") {
+ sources = [
+ "file_video_saver.js",
+ "intent_video_saver.js",
+ "video_saver_interface.js",
+ ]
+ deps = [
+ "..:intent",
+ ]
}
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 3be85b7f5c2..ba8aca34aad 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,11 +6,20 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
+ ":chrome_helper",
":device_operator",
":image_capture",
]
}
+js_library("chrome_helper") {
+ deps = [
+ "//components/arc/mojom:camera_intent_js_library_for_compile",
+ "//components/chromeos_camera/common:camera_app_helper_js_library_for_compile",
+ ]
+ externs_list = [ "$externs_path/pending.js" ]
+}
+
js_library("device_operator") {
deps = [
"//media/capture/video/chromeos/mojom:cros_camera_js_library_for_compile",
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
index 84560373b2c..d52516bb184 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/views/BUILD.gn
@@ -7,6 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni")
group("closure_compile") {
deps = [
":compile_resources",
+ "camera:compile_resources",
]
}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/BUILD.gn b/chromium/chrome/browser/resources/chromeos/camera/src/js/views/camera/BUILD.gn
index e27ead67627..38a22c262b9 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/js/views/camera/BUILD.gn
@@ -4,15 +4,21 @@
import("//third_party/closure_compiler/compile_js.gni")
-js_type_check("closure_compile") {
+group("closure_compile") {
deps = [
- ":viewer-form-warning",
+ ":compile_resources",
]
}
-js_library("viewer-form-warning") {
+js_type_check("compile_resources") {
deps = [
- "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
- "//ui/webui/resources/js:promise_resolver",
+ ":review_result",
+ ]
+}
+
+js_library("review_result") {
+ deps = [
+ "../..:state",
+ "../..:util",
]
}
diff --git a/chromium/chrome/browser/resources/chromeos/camera/src/manifest.json b/chromium/chrome/browser/resources/chromeos/camera/src/manifest.json
index 412686f9bed..f0c5c272c5b 100644
--- a/chromium/chrome/browser/resources/chromeos/camera/src/manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/camera/src/manifest.json
@@ -25,7 +25,14 @@
],
"app": {
"background": {
- "scripts": ["js/background.js"]
+ "scripts": [
+ "js/mojo/mojo_bindings_lite.js",
+ "js/mojo/camera_intent.mojom-lite.js",
+ "js/mojo/camera_app_helper.mojom-lite.js",
+ "js/mojo/chrome_helper.js",
+ "js/intent.js",
+ "js/background.js"
+ ]
}
}
}
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 299d99fff8c..f5c800a6df4 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
@@ -297,6 +297,12 @@
<message desc="Label for the button of grid-type options." name="IDS_GRID_TYPE_BUTTON">
Grid type
</message>
+ <message desc="Label showing current state of 30 FPS on tooltip of toggle 60 FPS recording checkbox." name="IDS_LABEL_30FPS">
+ 30 FPS
+ </message>
+ <message desc="Label showing current state of 60 FPS on tooltip of toggle 60 FPS recording checkbox." name="IDS_LABEL_60FPS">
+ 60 FPS
+ </message>
<message desc="Label for the checkbox to toggle 60 FPS recording." name="IDS_TOGGLE_60FPS_BUTTON">
60 FPS
</message>
@@ -315,17 +321,14 @@
<message desc="Label for switch to take portrait photo mode button." name="IDS_LABEL_SWITCH_TAKE_PORTRAIT_PHOTO_BUTTON">
Portrait
</message>
- <message desc="Title of banner shown for introducing new camera App UI." name="IDS_BANNER_TITLE">
- A whole new look
+ <message desc="Label for the confirm button to confirm with the reviewed photo or video." name="IDS_CONFIRM_REVIEW_BUTTON">
+ Confirm
</message>
- <message desc="Message in the banner shown for introducing new camera App UI." name="IDS_BANNER_MSG">
- Your camera now supports new modes and your photos and videos will be available under your Downloads folders.
- </message>
- <message desc="Label for close introducing new camera App UI banner button." name="IDS_BANNER_CLOSE_BUTTON">
- Close
+ <message desc="Label for the cancel button to cancel with the reviewed photo or video." name="IDS_CANCEL_REVIEW_BUTTON">
+ Cancel
</message>
- <message desc="Label for learn more about new camera App UI button." name="IDS_BANNER_LEARN_MORE_BUTTON">
- Learn more
+ <message desc="Label for the button to play video." name="IDS_PLAY_RESULT_VIDEO_BUTTON">
+ Play video
</message>
</messages>
</release>
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
index 39bba1fa5d9..5210a02ce52 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -158,6 +158,7 @@ chromevox_modules = [
"cvox2/background/panel_command.js",
"cvox2/background/panel_menu.js",
"cvox2/background/panel_menu_item.js",
+ "cvox2/background/phonetic_data.js",
"cvox2/background/recovery_strategy.js",
"cvox2/background/tree_dumper.js",
"cvox2/background/tree_walker.js",
@@ -187,6 +188,7 @@ chromevox_modules = [
"host/interface/braille_interface.js",
"host/interface/host_factory.js",
"host/interface/tts_interface.js",
+ "third_party/tamachiyomi/ja_phonetic_data.js",
"walkers/abstract_node_walker.js",
"walkers/abstract_selection_walker.js",
"walkers/abstract_shifter.js",
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
index ddee7a20815..f049fa2f5b9 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/chromevox/background/keymaps/next_keymap.json
@@ -924,6 +924,25 @@
}
},
{
+ "command": "previousSimilarItem",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [73],
+ "shiftKey": [true]
+ }
+ }
+ },
+ {
+ "command": "nextSimilarItem",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [73]
+ }
+ }
+ },
+ {
"command": "jumpToDetails",
"sequence": {
"cvoxModifier": true,
@@ -998,7 +1017,7 @@
}
},
{
- "command": "getBatteryDescription",
+ "command": "announceBatteryDescription",
"sequence": {
"cvoxModifier": true,
"keys": {
@@ -1007,13 +1026,22 @@
}
},
{
- "command": "getRichTextDescription",
+ "command": "announceRichTextDescription",
"sequence": {
"cvoxModifier": true,
"keys": {
"keyCode": [65, 70]
}
}
+ },
+ {
+ "command": "readPhoneticPronunciation",
+ "sequence": {
+ "cvoxModifier": true,
+ "keys": {
+ "keyCode": [65, 67]
+ }
+ }
}
]
}
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 2028ad38ee8..60b38c2f415 100644
--- a/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
+++ b/chromium/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -1072,6 +1072,21 @@
<message desc="This is an abbreviated ARIA widget role name shown on a braille display. When translating, try to find a contracted form of the translation for 'alert dialog' according to local conventions. If reasonable, use all lowercase and avoid punctuation to keep the number of characters as low as possible." name="IDS_CHROMEVOX_ROLE_ALERTDIALOG_BRL">
alrt dlg
</message>
+ <message desc="Accessibility role description for attribution, meaning authoring information tied to specific content" name="IDS_CHROMEVOX_ROLE_ANNOTATION_ATTRIBUTION">
+ Authoring info
+ </message>
+ <message desc="Accessibility role description for commentary" name="IDS_CHROMEVOX_ROLE_ANNOTATION_COMMENTARY">
+ Comments
+ </message>
+ <message desc="Accessibility role description for presence, meaning information about another collaborator who is currently reviewing or editing this content" name="IDS_CHROMEVOX_ROLE_ANNOTATION_PRESENCE">
+ Live presence
+ </message>
+ <message desc="Accessibility role description for revision, meaining historical change info tied to this content" name="IDS_CHROMEVOX_ROLE_ANNOTATION_REVISION">
+ Revision
+ </message>
+ <message desc="Accessibility role description for suggestion, meaning a suggested change to some content" name="IDS_CHROMEVOX_ROLE_ANNOTATION_SUGGESTION" >
+ Suggestion
+ </message>
<message desc="Describes an element with the ARIA role button." name="IDS_CHROMEVOX_ROLE_BUTTON">
Button
</message>
@@ -1900,6 +1915,8 @@
<message desc="In an editable text box, describes a line with only whitespace." name="IDS_CHROMEVOX_TEXT_BOX_WHITESPACE" meaning="UI element">
Space
</message>
+ <!-- TODO(crbug.com/999781): The following 3 messages are combined with other message fragments. -->
+ <!-- Combining message fragments is a I18N code-smell. Combine fragments into a single message. -->
<message desc="Further describes a list-like element with a number of items. e.g. This will be combined with other messages to produce: List with 3 items." name="IDS_CHROMEVOX_LIST_WITH_ITEMS_NOT_PLURALIZED">
with <ph name="num">$1</ph> items
</message>
@@ -1907,10 +1924,11 @@
+<ph name="num">$1</ph>
</message>
<message desc="Further describes a list-like element with a number of items. e.g. This will be combined with other messages to produce: List with 3 items." name="IDS_CHROMEVOX_LIST_WITH_ITEMS">
- with {COUNT, plural, =1 {# item}other {# items}}
+ {COUNT, plural, =1{with # item} other{with # items}}
</message>
+ <!-- TODO(crbug.com/999781): This should not need ICU msg format. Fix where the message is used. -->
<message desc="Further describes a list-like element with a number of items in braille." name="IDS_CHROMEVOX_LIST_WITH_ITEMS_BRL">
- +{COUNT, plural, =1 {#}other {#}}
+ {COUNT, plural, =1{+#} other{+#}}
</message>
<message desc="Describes the state of a progress bar, in percent." name="IDS_CHROMEVOX_STATE_PERCENT">
<ph name="num">$1</ph>%
@@ -2275,6 +2293,12 @@
<message desc="The description of the next group command. Displayed in the Options page." name="IDS_CHROMEVOX_NEXT_GROUP">
Next Group
</message>
+ <message desc="The description of the previous similar command." name="IDS_CHROMEVOX_PREVIOUS_SIMILAR_ITEM">
+ Previous similar item
+ </message>
+ <message desc="The description of the next similar item command." name="IDS_CHROMEVOX_NEXT_SIMILAR_ITEM">
+ Next similar item
+ </message>
<message desc="Describes nodes or anything describing them as a landmark." name="IDS_CHROMEVOX_ROLE_LANDMARK">
Landmark
</message>
@@ -3706,6 +3730,21 @@ If you're done with the tutorial, use ChromeVox to navigate to the Close button
<message desc="Appends language in front of content." name="IDS_CHROMEVOX_LANGUAGE_SWITCH">
<ph name="language">$1<ex>English</ex></ph>: <ph name="content">$2<ex>This is example content</ex></ph>
</message>
+ <message desc="The description of the readPhoneticPronunciation key. Displayed in the ChromeVox menu." name="IDS_CHROMEVOX_READ_PHONETIC_PRONUNCIATION">
+ Announce phonetic pronunciation for word
+ </message>
+ <message desc="Spoken to inform the user that the node's name is empty" name="IDS_CHROMEVOX_EMPTY_NAME">
+ No available text for this item
+ </message>
+ <message desc="The description of the announceBatteryDescription key. Displayed in the ChromeVox menu." name="IDS_CHROMEVOX_ANNOUNCE_BATTERY_DESCRIPTION">
+ Announce current battery status
+ </message>
+ <message desc="The description of the announceRichTextDescription key. Displayed in the ChromeVox menu." name="IDS_CHROMEVOX_ANNOUNCE_RICH_TEXT_DESCRIPTION">
+ Announce formatting for current item
+ </message>
+ <message desc="Announced when there is no available voice for a language." name="IDS_CHROMEVOX_VOICE_UNAVAILABLE_FOR_LANGUAGE">
+ No voice available for language: <ph name="language">$1<ex>English</ex></ph>
+ </message>
</messages>
</release>
</grit>
diff --git a/chromium/chrome/browser/resources/chromeos/crostini_installer/BUILD.gn b/chromium/chrome/browser/resources/chromeos/crostini_installer/BUILD.gn
new file mode 100644
index 00000000000..2ce6341b27d
--- /dev/null
+++ b/chromium/chrome/browser/resources/chromeos/crostini_installer/BUILD.gn
@@ -0,0 +1,44 @@
+# 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") {
+ is_polymer3 = true
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/chromeos/crostini_installer/",
+ "js_module_root=./gen/chrome/browser/resources/chromeos/crostini_installer/",
+ ]
+ deps = [
+ ":app",
+ ":browser_proxy",
+ ]
+}
+
+js_library("app") {
+ deps = [
+ ":browser_proxy",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ ]
+}
+
+js_library("browser_proxy") {
+ deps = [
+ "//chrome/browser/ui/webui/chromeos/crostini_installer:mojo_bindings_js_library_for_compile",
+ "//ui/webui/resources/js:cr.m",
+ ]
+}
+
+polymer_modulizer("app") {
+ js_file = "app.js"
+ html_file = "app.html"
+ html_type = "v3-ready"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":app_module",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json b/chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
index e59dd858d6c..5aae7aca66d 100644
--- a/chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
@@ -617,7 +617,8 @@
"id": "xkb:es::spa",
"description": "",
"language": [
- "es"
+ "es",
+ "es-ES"
],
"layouts": [
"es"
@@ -629,7 +630,7 @@
"name": "__MSG_keyboard_catalan__",
"type": "ime",
"id": "xkb:es:cat:cat",
- "indicator": "CAS",
+ "indicator": "CAT",
"description": "",
"language": [
"ca"
diff --git a/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json b/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
index 0bc467ac313..ca18e770961 100644
--- a/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
+++ b/chromium/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
@@ -483,7 +483,8 @@
"id": "xkb:es::spa",
"description": "",
"language": [
- "es"
+ "es",
+ "es-ES"
],
"layouts": [
"es"
@@ -494,7 +495,7 @@
"name": "__MSG_keyboard_catalan__",
"type": "ime",
"id": "xkb:es:cat:cat",
- "indicator": "CAS",
+ "indicator": "CAT",
"description": "",
"language": [
"ca"
diff --git a/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn b/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
index 02db3721b9f..5137ae377cc 100644
--- a/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/internet_config_dialog/BUILD.gn
@@ -25,9 +25,8 @@ js_type_check("closure_compile") {
js_library("internet_config_dialog") {
deps = [
"//ui/webui/resources/cr_components/chromeos/network:network_config",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
- "//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",
]
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 7f45f293dd0..c292ee7e2d0 100644
--- a/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/internet_detail_dialog/BUILD.gn
@@ -25,15 +25,11 @@ js_type_check("closure_compile") {
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/chromeos/network:cr_onc_strings",
"//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",
]
- externs_list = [
- "$externs_path/chrome_send.js",
- "$externs_path/networking_private.js",
- ]
- extra_sources = [ "$interfaces_path/networking_private_interface.js" ]
+ externs_list = [ "$externs_path/chrome_send.js" ]
}
diff --git a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
index 77459dd1bf6..a37b11a9538 100644
--- a/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -235,7 +235,7 @@ js_library("navigation_bar") {
js_library("network_select_login") {
deps = [
"//ui/webui/resources/cr_elements/chromeos/network:cr_network_select",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+ "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings",
"//ui/webui/resources/js/chromeos:onc_mojo",
]
}
diff --git a/chromium/chrome/browser/resources/chromeos/network_ui/BUILD.gn b/chromium/chrome/browser/resources/chromeos/network_ui/BUILD.gn
index 199569c5a92..dcc92a7bfb2 100644
--- a/chromium/chrome/browser/resources/chromeos/network_ui/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/network_ui/BUILD.gn
@@ -15,7 +15,7 @@ js_library("network_ui") {
"//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_icon",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+ "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:util",
"//ui/webui/resources/js/chromeos:onc_mojo",
diff --git a/chromium/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn b/chromium/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
index 7e924f7353c..ce57213b9dc 100644
--- a/chromium/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/set_time_dialog/BUILD.gn
@@ -3,8 +3,10 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
deps = [
":set_time_browser_proxy",
":set_time_dialog",
@@ -14,17 +16,29 @@ js_type_check("closure_compile") {
js_library("set_time_dialog") {
deps = [
":set_time_browser_proxy",
- "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
- "//ui/webui/resources/js:assert",
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:web_ui_listener_behavior",
+ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
+ "//ui/webui/resources/js:assert.m",
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
js_library("set_time_browser_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/chrome_send.js" ]
}
+
+polymer_modulizer("set_time_dialog") {
+ js_file = "set_time_dialog.js"
+ html_file = "set_time_dialog.html"
+ html_type = "v3-ready"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":set_time_dialog_module",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn b/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
index a38c408d0f3..34d99739608 100644
--- a/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
+++ b/chromium/chrome/browser/resources/chromeos/switch_access/BUILD.gn
@@ -36,6 +36,7 @@ run_jsbundler("switch_access_copied_files") {
"back_button_manager.js",
"background.js",
"commands.js",
+ "event_helper.js",
"focus_ring_manager.js",
"icons/back.svg",
"icons/copy.svg",
@@ -175,6 +176,7 @@ js_type_check("closure_compile") {
":back_button_manager",
":background",
":commands",
+ ":event_helper",
":focus_ring_manager",
":menu_manager",
":menu_panel",
@@ -203,6 +205,7 @@ js_library("auto_scan_manager") {
js_library("navigation_manager") {
deps = [
":back_button_manager",
+ ":event_helper",
":focus_ring_manager",
":menu_manager",
":menu_panel_interface",
@@ -231,6 +234,7 @@ js_library("background") {
js_library("back_button_manager") {
deps = [
":menu_panel_interface",
+ ":rect_helper",
]
externs_list = [
"$externs_path/accessibility_private.js",
@@ -244,6 +248,10 @@ js_library("commands") {
]
}
+js_library("event_helper") {
+ externs_list = [ "$externs_path/automation.js" ]
+}
+
js_library("focus_ring_manager") {
deps = [
":back_button_manager",
@@ -254,6 +262,7 @@ js_library("focus_ring_manager") {
js_library("menu_manager") {
deps = [
":menu_panel_interface",
+ ":rect_helper",
":switch_access_interface",
]
externs_list = [ "$externs_path/accessibility_private.js" ]
@@ -309,11 +318,15 @@ js_library("switch_access_predicate") {
}
js_library("text_input_manager") {
+ deps = [
+ ":event_helper",
+ ]
externs_list = [ "$externs_path/accessibility_private.js" ]
}
js_library("text_navigation_manager") {
deps = [
+ ":event_helper",
":switch_access_constants",
]
externs_list = [ "$externs_path/accessibility_private.js" ]
diff --git a/chromium/chrome/browser/resources/component_extension_resources.grd b/chromium/chrome/browser/resources/component_extension_resources.grd
index f159f9a242b..a534601664a 100644
--- a/chromium/chrome/browser/resources/component_extension_resources.grd
+++ b/chromium/chrome/browser/resources/component_extension_resources.grd
@@ -100,6 +100,7 @@
<include name="IDR_PDF_INDEX_CSS" file="pdf/index.css" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PDF_MAIN_JS" file="pdf/main.js" type="BINDATA" />
<include name="IDR_PDF_PDF_VIEWER_JS" file="pdf/pdf_viewer.js" type="BINDATA" />
+ <include name="IDR_PDF_CONTROLLER_JS" file="pdf/controller.js" type="BINDATA" />
<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" />
@@ -113,35 +114,38 @@
<include name="IDR_PDF_METRICS_JS" file="pdf/metrics.js" type="BINDATA" />
<include name="IDR_PDF_SHARED_VARS_HTML" file="pdf/elements/shared-vars.html" type="BINDATA" />
+ <!-- TODO(crbug.com/1005029): Dummy generated file used for ChromeComponentExtensionResourceManager tests.
+ Replace with a file actually used by the PDF Viewer once migration to Polymer3 is completed. -->
+ <include name="IDR_PDF_SHARED_VARS_M_JS" file="${root_gen_dir}/chrome/browser/resources/pdf/elements/shared-vars.m.js" use_base_dir="false" type="BINDATA" />
<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_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" />
+ <include name="IDR_PDF_VIEWER_BOOKMARK_HTML" file="pdf/elements/viewer-bookmark.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_BOOKMARK_JS" file="pdf/elements/viewer-bookmark.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ERROR_SCREEN_HTML" file="pdf/elements/viewer-error-screen.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ERROR_SCREEN_JS" file="pdf/elements/viewer-error-screen.js" type="BINDATA" />
<if expr="chromeos">
<include name="IDR_PDF_VIEWER_INK_INDEX_HTML" file="pdf/ink/index.html" type="BINDATA" />
<include name="IDR_PDF_VIEWER_INK_INK_API_JS" file="pdf/ink/ink_api.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_INK_HOST_HTML" file="pdf/elements/viewer-ink-host/viewer-ink-host.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_INK_HOST_JS" file="pdf/elements/viewer-ink-host/viewer-ink-host.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PEN_OPTIONS_HTML" file="pdf/elements/viewer-pen-options/viewer-pen-options.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PEN_OPTIONS_JS" file="pdf/elements/viewer-pen-options/viewer-pen-options.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_FORM_WARNING_HTML" file="pdf/elements/viewer-form-warning/viewer-form-warning.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_FORM_WARNING_JS" file="pdf/elements/viewer-form-warning/viewer-form-warning.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_INK_HOST_HTML" file="pdf/elements/viewer-ink-host.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_INK_HOST_JS" file="pdf/elements/viewer-ink-host.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PEN_OPTIONS_HTML" file="pdf/elements/viewer-pen-options.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PEN_OPTIONS_JS" file="pdf/elements/viewer-pen-options.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_FORM_WARNING_HTML" file="pdf/elements/viewer-form-warning.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_FORM_WARNING_JS" file="pdf/elements/viewer-form-warning.js" type="BINDATA" />
</if>
- <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_HTML" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_JS" file="pdf/elements/viewer-page-indicator/viewer-page-indicator.js" type="BINDATA" flattenhtml="true" />
- <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_HTML" file="pdf/elements/viewer-page-selector/viewer-page-selector.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_JS" file="pdf/elements/viewer-page-selector/viewer-page-selector.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_HTML" file="pdf/elements/viewer-password-screen/viewer-password-screen.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_JS" file="pdf/elements/viewer-password-screen/viewer-password-screen.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_HTML" file="pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html" type="BINDATA" preprocess="true" />
- <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_JS" file="pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_HTML" file="pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_JS" file="pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ZOOM_BUTTON_HTML" file="pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ZOOM_BUTTON_JS" file="pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.js" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_HTML" file="pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html" type="BINDATA" />
- <include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_JS" file="pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_HTML" file="pdf/elements/viewer-page-indicator.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PAGE_INDICATOR_JS" file="pdf/elements/viewer-page-indicator.js" type="BINDATA" flattenhtml="true" />
+ <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_HTML" file="pdf/elements/viewer-page-selector.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PAGE_SELECTOR_JS" file="pdf/elements/viewer-page-selector.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_HTML" file="pdf/elements/viewer-password-screen.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PASSWORD_SCREEN_JS" file="pdf/elements/viewer-password-screen.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_HTML" file="pdf/elements/viewer-pdf-toolbar.html" type="BINDATA" preprocess="true" />
+ <include name="IDR_PDF_VIEWER_PDF_TOOLBAR_JS" file="pdf/elements/viewer-pdf-toolbar.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_HTML" file="pdf/elements/viewer-toolbar-dropdown.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_TOOLBAR_DROPDOWN_JS" file="pdf/elements/viewer-toolbar-dropdown.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ZOOM_BUTTON_HTML" file="pdf/elements/viewer-zoom-button.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ZOOM_BUTTON_JS" file="pdf/elements/viewer-zoom-button.js" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_HTML" file="pdf/elements/viewer-zoom-toolbar.html" type="BINDATA" />
+ <include name="IDR_PDF_VIEWER_ZOOM_SELECTOR_JS" file="pdf/elements/viewer-zoom-toolbar.js" type="BINDATA" />
</if>
<include name="IDR_CRYPTOTOKEN_UTIL_JS" file="cryptotoken/util.js" type="BINDATA" />
<include name="IDR_CRYPTOTOKEN_B64_JS" file="cryptotoken/b64.js" type="BINDATA" />
diff --git a/chromium/chrome/browser/resources/conflicts/about_conflicts.html b/chromium/chrome/browser/resources/conflicts/about_conflicts.html
index efeabe223b0..c8da460f8c8 100644
--- a/chromium/chrome/browser/resources/conflicts/about_conflicts.html
+++ b/chromium/chrome/browser/resources/conflicts/about_conflicts.html
@@ -11,7 +11,7 @@ body {
a {
color: blue;
- font-size: 103%;
+ text-decoration: none;
}
#header {
@@ -96,8 +96,8 @@ div.content {
padding-top: 5px;
}
-.module {
- border-bottom: 1px solid #cdcdcd;
+.module:hover {
+ background: rgb(255, 255, 170);
}
.module-name {
@@ -110,23 +110,10 @@ div.content {
text-align: center;
}
-.suspected-bad {
- color: rgb(221, 119, 0);
-}
-
-.confirmed-bad {
- color: red;
-}
-
.nowrap {
white-space: nowrap;
}
-.extra-info-text {
- margin-bottom: 1em;
- margin-top: -1em;
-}
-
.clearing {
clear: left;
float: left;
@@ -150,7 +137,9 @@ html[dir=rtl] .clearing {
<div id="header"><h1>Modules loaded</h1></div>
<div id="blurb-container">
- <span>This page lists all modules loaded into the browser and renderer processes and modules registered to load at a later point.</span>
+ <span>This page lists <a href="#">all</a> modules loaded into the
+ <a href="#B">browser</a> and <a href="#R">renderer</a> processes and
+ modules registered to load at a <a href="#None">later</a> point.</span>
</div>
<div id="modulesTemplate">
@@ -211,7 +200,8 @@ html[dir=rtl] .clearing {
<span dir="ltr">Conflicts Status</span>
</td>
</tr>
- <tr jsselect="moduleList">
+ <tr jsvalues="data-process:process_types.toLowerCase()"
+ jsselect="moduleList" class="module">
<td valign="top" class="datacell">
<span dir="ltr"
jsvalues=".innerHTML:description"
diff --git a/chromium/chrome/browser/resources/conflicts/about_conflicts.js b/chromium/chrome/browser/resources/conflicts/about_conflicts.js
index eb750549ea5..f44af07a016 100644
--- a/chromium/chrome/browser/resources/conflicts/about_conflicts.js
+++ b/chromium/chrome/browser/resources/conflicts/about_conflicts.js
@@ -43,15 +43,35 @@ function requestModuleListData() {
}
/**
+ * Filters list of displayed modules to those listed in the process types
+ * specified in the url fragment. For instance, chrome://conflicts/#r will show
+ * only those modules that have loaded into a renderer.
+ */
+function filterModuleListData() {
+ const filter = window.location.hash.substr(1).toLowerCase();
+ const modules = document.getElementsByClassName('module');
+
+ // Loop through all modules, and hide all that don't match the filter.
+ for (i = 0; i < modules.length; ++i) {
+ modules[i].style.display =
+ modules[i].dataset.process.includes(filter) ? '' : 'none';
+ }
+}
+
+/**
* Called by the WebUI to re-populate the page with data representing the
* current state of installed modules.
* @param {Object} moduleListData Information about available modules.
*/
function returnModuleList(moduleListData) {
renderTemplate(moduleListData);
+ if (window.location.hash.length > 1) {
+ filterModuleListData();
+ }
$('loading-message').style.visibility = 'hidden';
$('body-container').style.visibility = 'visible';
}
// Get data and have it displayed upon loading.
document.addEventListener('DOMContentLoaded', requestModuleListData);
+window.addEventListener('hashchange', filterModuleListData, false);
diff --git a/chromium/chrome/browser/resources/cryptotoken/enroller.js b/chromium/chrome/browser/resources/cryptotoken/enroller.js
index 7bde035b0a1..fd81423f478 100644
--- a/chromium/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chromium/chrome/browser/resources/cryptotoken/enroller.js
@@ -352,6 +352,18 @@ var ConveyancePreference = {
};
/**
+ * WebAuthnAttestationConveyancePreference is the
+ * AttestationConveyancePreference enum from WebAuthn.
+ * @enum{string}
+ */
+const WebAuthnAttestationConveyancePreference = {
+ NONE: 'none',
+ INDIRECT: 'indirect',
+ DIRECT: 'direct',
+ ENTERPRISE: 'enterprise',
+};
+
+/**
* conveyancePreference returns the attestation certificate replacement mode.
*
* @param {EnrollChallenge} enrollChallenge
@@ -397,12 +409,14 @@ function handleU2fEnrollRequest(messageSender, request, sendResponse) {
if (conveyancePreference(enrollChallenge) == ConveyancePreference.NONE) {
isDirect = false;
} else if (chrome.cryptotokenPrivate != null) {
- isDirect = await(new Promise((resolve, reject) => {
+ isDirect = await (new Promise((resolve, reject) => {
chrome.cryptotokenPrivate.canAppIdGetAttestation(
- {'appId': appId,
- 'tabId': messageSender.tab.id,
- 'origin': sender.origin,
- }, resolve);
+ {
+ 'appId': appId,
+ 'tabId': messageSender.tab.id,
+ 'origin': sender.origin,
+ },
+ resolve);
}));
}
@@ -821,11 +835,11 @@ Enroller.prototype.sendEnrollRequestToHelper_ = function() {
let v2Challenge;
for (let index = 0; index < self.enrollChallenges_.length; index++) {
if (self.enrollChallenges_[index]['version'] === 'U2F_V2') {
- v2Challenge = self.enrollChallenges_[index]['challenge'];
+ v2Challenge = self.enrollChallenges_[index];
}
}
- if (v2Challenge === undefined) {
+ if (v2Challenge['challenge'] === undefined) {
console.warn('Did not find U2F_V2 challenge');
this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST});
return;
@@ -844,23 +858,39 @@ const googleCorpAppId =
* @private
*/
Enroller.prototype.doRegisterWebAuthn_ = function(appId, challenge, request) {
+ const encodedChallenge = challenge['challenge'];
+
if (appId == googleCorpAppId) {
- this.doRegisterWebAuthnContinue_(appId, challenge, request, true);
+ this.doRegisterWebAuthnContinue_(
+ appId, encodedChallenge, request,
+ WebAuthnAttestationConveyancePreference.ENTERPRISE);
return;
}
+ const attestationPreference =
+ conveyancePreference(challenge) == ConveyancePreference.DIRECT ?
+ WebAuthnAttestationConveyancePreference.DIRECT :
+ WebAuthnAttestationConveyancePreference.NONE;
+
if (!chrome.cryptotokenPrivate) {
- this.doRegisterWebAuthnContinue_(appId, challenge, request, false);
+ this.doRegisterWebAuthnContinue_(
+ appId, encodedChallenge, request, attestationPreference);
return;
}
chrome.cryptotokenPrivate.isAppIdHashInEnterpriseContext(
decodeWebSafeBase64ToArray(B64_encode(sha256HashOfString(appId))),
- this.doRegisterWebAuthnContinue_.bind(this, appId, challenge, request));
+ (enterprise_context) => {
+ this.doRegisterWebAuthnContinue_(
+ appId, encodedChallenge, request,
+ enterprise_context ?
+ WebAuthnAttestationConveyancePreference.ENTERPRISE :
+ attestationPreference);
+ });
};
Enroller.prototype.doRegisterWebAuthnContinue_ = function(
- appId, challenge, request, useIndividualAttestation) {
+ appId, challenge, request, attestationMode) {
// Set a random ID.
const randomId = new Uint8Array(new ArrayBuffer(16));
crypto.getRandomValues(randomId);
@@ -895,7 +925,6 @@ Enroller.prototype.doRegisterWebAuthnContinue_ = function(
// Request enterprise attestation for the gstatic corp App ID and domains
// whitelisted via enterprise policy. Otherwise request 'direct' attestation
// (which might later get stripped).
- const attestationMode = useIndividualAttestation ? 'enterprise' : 'direct';
const options = {
publicKey: {
rp: {
diff --git a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css b/chromium/chrome/browser/resources/dev_ui/dev_ui_loader_error.html
index aa35e0acfab..76ca63ebc52 100644
--- a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.css
+++ b/chromium/chrome/browser/resources/dev_ui/dev_ui_loader_error.html
@@ -1,7 +1,10 @@
-/* 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. */
-
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>DevUI DFM Loader</title>
+ <style>
body {
align-items: center;
display: flex;
@@ -11,11 +14,6 @@ body {
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;
@@ -43,3 +41,16 @@ ul.suggestions-list li {
color: #2B2B2B;
line-height: 1.55;
}
+ </style>
+</head>
+<body>
+<div id="failure-message">
+ <h1 class="heading">$i18n{h1}</h1>
+ <p class="list-header">$i18n{p}</p>
+ <ul class="suggestions-list">
+ <li>$i18n{li-1}</li>
+ <li>$i18n{li-2}</li>
+ </ul>
+</div>
+</body>
+</html>
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
deleted file mode 100644
index 547e30b812d..00000000000
--- a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.grdp
+++ /dev/null
@@ -1,6 +0,0 @@
-<?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
deleted file mode 100644
index fc95229fb39..00000000000
--- a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!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
deleted file mode 100644
index 61bc4c25be8..00000000000
--- a/chromium/chrome/browser/resources/dev_ui_loader/dev_ui_loader.js
+++ /dev/null
@@ -1,51 +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.
-
-(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/discards/BUILD.gn b/chromium/chrome/browser/resources/discards/BUILD.gn
index abe3f6ba262..8cdbf0b7951 100644
--- a/chromium/chrome/browser/resources/discards/BUILD.gn
+++ b/chromium/chrome/browser/resources/discards/BUILD.gn
@@ -50,7 +50,6 @@ js_library("discards_tab") {
js_library("graph_tab") {
deps = [
- "//chrome/browser/performance_manager:mojo_bindings_js_library_for_compile",
"//chrome/browser/ui/webui/discards:mojo_bindings_js_library_for_compile",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
@@ -59,7 +58,7 @@ js_library("graph_tab") {
js_library("graph_doc") {
deps = [
- "//chrome/browser/performance_manager:mojo_bindings_js_library_for_compile",
+ "//chrome/browser/ui/webui/discards:mojo_bindings_js_library_for_compile",
]
externs_list = [ "../../../../third_party/d3/src/externs.js" ]
diff --git a/chromium/chrome/browser/resources/discards/database_tab.js b/chromium/chrome/browser/resources/discards/database_tab.js
index 1fc56fbba26..f8a9e74e9d7 100644
--- a/chromium/chrome/browser/resources/discards/database_tab.js
+++ b/chromium/chrome/browser/resources/discards/database_tab.js
@@ -7,10 +7,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their origin.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -20,10 +20,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their dirty bit.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -33,10 +33,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their last load time.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -46,10 +46,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their CPU usage.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -63,10 +63,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their memory usage.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -82,10 +82,10 @@ cr.define('database_tab', function() {
/**
* Compares two db rows by their load duration.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} a The first value being
- * compared.
- * @param {mojom.SiteCharacteristicsDatabaseEntry} b The second value being
- * compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} a The first value
+ * being compared.
+ * @param {discards.mojom.SiteCharacteristicsDatabaseEntry} b The second value
+ * being compared.
* @return {number} A negative number if a < b, 0 if a == b, and a positive
* number if a > b.
*/
@@ -101,8 +101,8 @@ cr.define('database_tab', function() {
/**
* @param {string} sortKey The sort key to get a function for.
- * @return {function(mojom.SiteCharacteristicsDatabaseEntry,
- mojom.SiteCharacteristicsDatabaseEntry): number}
+ * @return {function(discards.mojom.SiteCharacteristicsDatabaseEntry,
+ discards.mojom.SiteCharacteristicsDatabaseEntry): number}
* A comparison function that compares two tab infos, returns
* negative number if a < b, 0 if a == b, and a positive
* number if a > b.
@@ -194,7 +194,7 @@ Polymer({
properties: {
/**
* List of database rows.
- * @private {?Array<!mojom.SiteCharacteristicsDatabaseEntry>}
+ * @private {?Array<!discards.mojom.SiteCharacteristicsDatabaseEntry>}
*/
rows_: {
type: Array,
@@ -202,7 +202,7 @@ Polymer({
/**
* The database size response.
- * @private {!mojom.SiteCharacteristicsDatabaseSize}
+ * @private {!discards.mojom.SiteCharacteristicsDatabaseSize}
*/
size_: {
type: Object,
@@ -227,7 +227,7 @@ Polymer({
/** @private {!Object} */
requestedOrigins_: {},
- /** @private {?mojom.DiscardsDetailsProviderRemote} */
+ /** @private {?discards.mojom.DetailsProviderRemote} */
discardsDetailsProvider_: null,
/** @override */
@@ -399,7 +399,7 @@ Polymer({
},
/**
- * @param {?mojom.SiteCharacteristicsFeature} feature The feature
+ * @param {?discards.mojom.SiteCharacteristicsFeature} feature The feature
* in question.
* @return {string} A human-readable string representing the feature.
* @private
diff --git a/chromium/chrome/browser/resources/discards/discards.js b/chromium/chrome/browser/resources/discards/discards.js
index 1e8740a01f1..ea65798e9e6 100644
--- a/chromium/chrome/browser/resources/discards/discards.js
+++ b/chromium/chrome/browser/resources/discards/discards.js
@@ -10,11 +10,11 @@ cr.define('discards', function() {
let discardsDetailsProvider;
/**
- * @return {!mojom.DiscardsDetailsProviderRemote} Provides discards details.
+ * @return {!discards.mojom.DetailsProviderRemote} Provides discards details.
*/
function getOrCreateDetailsProvider() {
if (!discardsDetailsProvider) {
- discardsDetailsProvider = mojom.DiscardsDetailsProvider.getRemote();
+ discardsDetailsProvider = discards.mojom.DetailsProvider.getRemote();
}
return discardsDetailsProvider;
}
diff --git a/chromium/chrome/browser/resources/discards/discards_tab.js b/chromium/chrome/browser/resources/discards/discards_tab.js
index b7a64869944..58cccce5e4e 100644
--- a/chromium/chrome/browser/resources/discards/discards_tab.js
+++ b/chromium/chrome/browser/resources/discards/discards_tab.js
@@ -89,7 +89,7 @@ Polymer({
properties: {
/**
* List of tabinfos.
- * @private {?Array<!mojom.TabDiscardsInfo>}
+ * @private {?Array<!discards.mojom.TabDiscardsInfo>}
*/
tabInfos_: {
type: Array,
@@ -99,7 +99,7 @@ Polymer({
/** @private The current update timer if any. */
updateTimer_: 0,
- /** @private {(mojom.DiscardsDetailsProviderRemote|null)} */
+ /** @private {(discards.mojom.DetailsProviderRemote|null)} */
discardsDetailsProvider_: null,
/** @override */
@@ -137,17 +137,18 @@ Polymer({
/**
* Returns a string representation of a visibility enum value for display in
* a table.
- * @param {mojom.LifecycleUnitVisibility} visibility A visibility value.
+ * @param {discards.mojom.LifecycleUnitVisibility} visibility A visibility
+ * value.
* @return {string} A string representation of the visibility.
* @private
*/
visibilityToString_: function(visibility) {
switch (visibility) {
- case mojom.LifecycleUnitVisibility.HIDDEN:
+ case discards.mojom.LifecycleUnitVisibility.HIDDEN:
return 'hidden';
- case mojom.LifecycleUnitVisibility.OCCLUDED:
+ case discards.mojom.LifecycleUnitVisibility.OCCLUDED:
return 'occluded';
- case mojom.LifecycleUnitVisibility.VISIBLE:
+ case discards.mojom.LifecycleUnitVisibility.VISIBLE:
return 'visible';
}
assertNotReached('Unknown visibility: ' + visibility);
@@ -196,7 +197,8 @@ Polymer({
* @param {mojom.LifecycleUnitState} state The lifecycle state.
* @param {mojom.LifecycleUnitDiscardReason} reason The discard reason. This
* is only used if the state is discard related.
- * @param {mojom.LifecycleUnitVisibility} visibility A visibility value.
+ * @param {discards.mojom.LifecycleUnitVisibility} visibility A visibility
+ * value.
* @param {boolean} hasFocus Whether or not the tab has input focus.
* @param {mojoBase.mojom.TimeDelta} stateChangeTime Delta between Unix Epoch
* and time at which the lifecycle state has changed.
@@ -208,11 +210,11 @@ Polymer({
state, reason, visibility, hasFocus, stateChangeTime) {
const pageLifecycleStateFromVisibilityAndFocus = function() {
switch (visibility) {
- case mojom.LifecycleUnitVisibility.HIDDEN:
- case mojom.LifecycleUnitVisibility.OCCLUDED:
+ case discards.mojom.LifecycleUnitVisibility.HIDDEN:
+ case discards.mojom.LifecycleUnitVisibility.OCCLUDED:
// An occluded page is also considered hidden.
return 'hidden';
- case mojom.LifecycleUnitVisibility.VISIBLE:
+ case discards.mojom.LifecycleUnitVisibility.VISIBLE:
return hasFocus ? 'active' : 'passive';
}
assertNotReached('Unknown visibility: ' + visibility);
@@ -269,7 +271,7 @@ Polymer({
/**
* Formats an items reactivation for display.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {string} The formatted reactivation score.
* @private
*/
@@ -280,7 +282,7 @@ Polymer({
/**
* Formats an items site engagement score for display.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {string} The formatted site engagemetn score.
* @private
*/
@@ -290,7 +292,7 @@ Polymer({
/**
* Retrieves favicon style tag value for an item.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {string} A style to retrieve and display the item's favicon.
* @private
*/
@@ -301,7 +303,7 @@ Polymer({
/**
* Formats an items lifecycle state for display.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {string} A human readable lifecycle state.
* @private
*/
@@ -338,7 +340,7 @@ Polymer({
/**
* Tests whether an item has reasons why it cannot be frozen.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {boolean} true iff there are reasons why the item cannot be frozen.
* @private
*/
@@ -347,7 +349,7 @@ Polymer({
},
/**
* Tests whether an item has reasons why it cannot be discarded.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {boolean} true iff there are reasons why the item cannot be
* discarded.
* @private
@@ -358,7 +360,7 @@ Polymer({
/**
* Tests whether an item can be loaded.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {boolean} true iff the item can be loaded.
* @private
*/
@@ -368,13 +370,13 @@ Polymer({
/**
* Tests whether an item can be frozen.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {boolean} true iff the item can be frozen.
* @private
*/
canFreeze_: function(item) {
- if (item.visibility == mojom.LifecycleUnitVisibility.HIDDEN ||
- item.visibility == mojom.LifecycleUnitVisibility.OCCLUDED) {
+ if (item.visibility == discards.mojom.LifecycleUnitVisibility.HIDDEN ||
+ item.visibility == discards.mojom.LifecycleUnitVisibility.OCCLUDED) {
// Only tabs that aren't visible can be frozen for now.
switch (item.state) {
case mojom.LifecycleUnitState.DISCARDED:
@@ -390,13 +392,13 @@ Polymer({
/**
* Tests whether an item can be discarded.
- * @param {mojom.TabDiscardsInfo} item The item in question.
+ * @param {discards.mojom.TabDiscardsInfo} item The item in question.
* @return {boolean} true iff the item can be discarded.
* @private
*/
canDiscard_: function(item) {
- if (item.visibility == mojom.LifecycleUnitVisibility.HIDDEN ||
- item.visibility == mojom.LifecycleUnitVisibility.OCCLUDED) {
+ if (item.visibility == discards.mojom.LifecycleUnitVisibility.HIDDEN ||
+ item.visibility == discards.mojom.LifecycleUnitVisibility.OCCLUDED) {
// Only tabs that aren't visible can be discarded for now.
switch (item.state) {
case mojom.LifecycleUnitState.DISCARDED:
diff --git a/chromium/chrome/browser/resources/discards/graph_doc.js b/chromium/chrome/browser/resources/discards/graph_doc.js
index 959cb80ae5b..ad07b1fa090 100644
--- a/chromium/chrome/browser/resources/discards/graph_doc.js
+++ b/chromium/chrome/browser/resources/discards/graph_doc.js
@@ -104,10 +104,10 @@ class GraphNode {
}
class PageNode extends GraphNode {
- /** @param {!performanceManager.mojom.WebUIPageInfo} page */
+ /** @param {!discards.mojom.PageInfo} page */
constructor(page) {
super(page.id);
- /** @type {!performanceManager.mojom.WebUIPageInfo} */
+ /** @type {!discards.mojom.PageInfo} */
this.page = page;
this.y = kPageNodesTargetY;
}
@@ -135,10 +135,10 @@ class PageNode extends GraphNode {
}
class FrameNode extends GraphNode {
- /** @param {!performanceManager.mojom.WebUIFrameInfo} frame */
+ /** @param {!discards.mojom.FrameInfo} frame */
constructor(frame) {
super(frame.id);
- /** @type {!performanceManager.mojom.WebUIFrameInfo} frame */
+ /** @type {!discards.mojom.FrameInfo} frame */
this.frame = frame;
this.color = this.selectColor(frame.processId);
}
@@ -168,10 +168,10 @@ class FrameNode extends GraphNode {
}
class ProcessNode extends GraphNode {
- /** @param {!performanceManager.mojom.WebUIProcessInfo} process */
+ /** @param {!discards.mojom.ProcessInfo} process */
constructor(process) {
super(process.id);
- /** @type {!performanceManager.mojom.WebUIProcessInfo} */
+ /** @type {!discards.mojom.ProcessInfo} */
this.process = process;
this.color = this.selectColor(process.id);
@@ -234,7 +234,7 @@ function bounding_force(graph_height) {
}
/**
- * @implements {performanceManager.mojom.WebUIGraphChangeStreamInterface}
+ * @implements {discards.mojom.GraphChangeStreamInterface}
*/
class Graph {
/**
@@ -377,31 +377,31 @@ class Graph {
switch (type) {
case 'frameCreated':
this.frameCreated(
- /** @type {!performanceManager.mojom.WebUIFrameInfo} */ (data));
+ /** @type {!discards.mojom.FrameInfo} */ (data));
break;
case 'pageCreated':
this.pageCreated(
- /** @type {!performanceManager.mojom.WebUIPageInfo} */ (data));
+ /** @type {!discards.mojom.PageInfo} */ (data));
break;
case 'processCreated':
this.processCreated(
- /** @type {!performanceManager.mojom.WebUIProcessInfo} */ (data));
+ /** @type {!discards.mojom.ProcessInfo} */ (data));
break;
case 'frameChanged':
this.frameChanged(
- /** @type {!performanceManager.mojom.WebUIFrameInfo} */ (data));
+ /** @type {!discards.mojom.FrameInfo} */ (data));
break;
case 'pageChanged':
this.pageChanged(
- /** @type {!performanceManager.mojom.WebUIPageInfo} */ (data));
+ /** @type {!discards.mojom.PageInfo} */ (data));
break;
case 'processChanged':
this.processChanged(
- /** @type {!performanceManager.mojom.WebUIProcessInfo} */ (data));
+ /** @type {!discards.mojom.ProcessInfo} */ (data));
break;
case 'favIconDataAvailable':
this.favIconDataAvailable(
- /** @type {!performanceManager.mojom.WebUIFavIconInfo} */ (data));
+ /** @type {!discards.mojom.FavIconInfo} */ (data));
break;
case 'nodeDeleted':
this.nodeDeleted(/** @type {number} */ (data));
diff --git a/chromium/chrome/browser/resources/discards/graph_tab.js b/chromium/chrome/browser/resources/discards/graph_tab.js
index c4538c5718f..1ac3f9b9f34 100644
--- a/chromium/chrome/browser/resources/discards/graph_tab.js
+++ b/chromium/chrome/browser/resources/discards/graph_tab.js
@@ -5,9 +5,9 @@
cr.define('graph_tab', function() {
'use strict';
/**
- * @implements {performanceManager.mojom.WebUIGraphChangeStreamInterface}
+ * @implements {discards.mojom.GraphChangeStreamInterface}
*/
- class WebUIGraphChangeStreamImpl {
+ class DiscardsGraphChangeStreamImpl {
constructor(contentWindow) {
this.contentWindow_ = contentWindow;
}
@@ -62,7 +62,7 @@ cr.define('graph_tab', function() {
}
return {
- WebUIGraphChangeStreamImpl: WebUIGraphChangeStreamImpl,
+ DiscardsGraphChangeStreamImpl: DiscardsGraphChangeStreamImpl,
};
});
@@ -72,20 +72,20 @@ Polymer({
/**
* The Mojo graph data source.
*
- * @private {performanceManager.mojom.WebUIGraphDumpRemote}
+ * @private {discards.mojom.GraphDumpRemote}
*/
graphDump_: null,
/**
* The graph change listener.
*
- * @private {performanceManager.mojom.WebUIGraphChangeStreamInterface}
+ * @private {discards.mojom.GraphChangeStreamInterface}
*/
changeListener_: null,
/** @override */
ready: function() {
- this.graphDump_ = performanceManager.mojom.WebUIGraphDump.getRemote();
+ this.graphDump_ = discards.mojom.GraphDump.getRemote();
},
/** @override */
@@ -97,10 +97,10 @@ Polymer({
/** @private */
onWebViewReady_: function() {
- this.changeListener_ =
- new graph_tab.WebUIGraphChangeStreamImpl(this.$.webView.contentWindow);
- this.client_ = new performanceManager.mojom.WebUIGraphChangeStreamReceiver(
- this.changeListener_);
+ this.changeListener_ = new graph_tab.DiscardsGraphChangeStreamImpl(
+ this.$.webView.contentWindow);
+ this.client_ =
+ new discards.mojom.GraphChangeStreamReceiver(this.changeListener_);
// Save helper to work around closure compiler bug: https://crbug.com/969212
const helper = this.client_.$;
diff --git a/chromium/chrome/browser/resources/discards/mojo_api.html b/chromium/chrome/browser/resources/discards/mojo_api.html
index 2dd0baa6b43..fa352178ff6 100644
--- a/chromium/chrome/browser/resources/discards/mojo_api.html
+++ b/chromium/chrome/browser/resources/discards/mojo_api.html
@@ -11,4 +11,3 @@ found in the LICENSE file.
src="chrome/browser/resource_coordinator/lifecycle_unit_state.mojom-lite.js">
</script>
<script src="chrome/browser/ui/webui/discards/discards.mojom-lite.js"></script>
-<script src="mojom/webui_graph_dump.mojom-lite.js"></script>
diff --git a/chromium/chrome/browser/resources/download_internals/BUILD.gn b/chromium/chrome/browser/resources/download_internals/BUILD.gn
index e1314cfd5de..1d0ff828cdb 100644
--- a/chromium/chrome/browser/resources/download_internals/BUILD.gn
+++ b/chromium/chrome/browser/resources/download_internals/BUILD.gn
@@ -15,6 +15,7 @@ js_type_check("closure_compile") {
js_library("download_internals") {
deps = [
":download_internals_browser_proxy",
+ "//third_party/jstemplate:jstemplate",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:util",
diff --git a/chromium/chrome/browser/resources/download_internals/download_internals.html b/chromium/chrome/browser/resources/download_internals/download_internals.html
index 62b2d8c3794..9c60f4f637b 100644
--- a/chromium/chrome/browser/resources/download_internals/download_internals.html
+++ b/chromium/chrome/browser/resources/download_internals/download_internals.html
@@ -4,14 +4,12 @@
<meta charset="utf-8">
<title>Download Internals</title>
<meta name="viewport" content="width=device-width">
- <link rel="stylesheet" href="chrome://resources/css/list.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="download_internals.css">
- <link rel="import" href="chrome://resources/html/cr.html">
- <link rel="import" href="chrome://resources/html/cr/ui/list_item.html">
- <link rel="import" href="chrome://resources/html/cr/ui/list.html">
- <link rel="import" href="chrome://resources/html/util.html">
+ <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="download_internals_browser_proxy.js"></script>
<script src="download_internals.js"></script>
diff --git a/chromium/chrome/browser/resources/downloads/BUILD.gn b/chromium/chrome/browser/resources/downloads/BUILD.gn
index eb003e5f9e1..7fceff2e48b 100644
--- a/chromium/chrome/browser/resources/downloads/BUILD.gn
+++ b/chromium/chrome/browser/resources/downloads/BUILD.gn
@@ -118,6 +118,7 @@ js_library("item") {
"//ui/webui/resources/js/cr/ui:focus_row_behavior",
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
+ externs_list = [ "$externs_path/pending_polymer.js" ]
}
js_library("manager") {
diff --git a/chromium/chrome/browser/resources/downloads/item.html b/chromium/chrome/browser/resources/downloads/item.html
index 16252c86252..cd2f60d97f3 100644
--- a/chromium/chrome/browser/resources/downloads/item.html
+++ b/chromium/chrome/browser/resources/downloads/item.html
@@ -295,7 +295,7 @@
}
</style>
- <div id="date">[[computeDate_(data.hideDate,
+ <div id="date" role="heading" aria-level="2">[[computeDate_(data.hideDate,
data.sinceString,
data.dateString)]]</div>
diff --git a/chromium/chrome/browser/resources/extensions/BUILD.gn b/chromium/chrome/browser/resources/extensions/BUILD.gn
index 1798f6238a7..734470fdaf4 100644
--- a/chromium/chrome/browser/resources/extensions/BUILD.gn
+++ b/chromium/chrome/browser/resources/extensions/BUILD.gn
@@ -7,46 +7,48 @@ import("//third_party/closure_compiler/compile_js.gni")
import("//tools/grit/grit_rule.gni")
import("../optimize_webui.gni")
-extensions_pak_file = "extensions_resources.pak"
-unpak_folder = "extensions_resources.unpak"
-
-optimize_webui("build") {
- host = "extensions"
- html_in_files = [ "extensions.html" ]
- html_out_files = [ "vulcanized.html" ]
- insert_in_head = "<base href=\"chrome://extensions\">"
- input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir)
- js_out_files = [ "crisper.js" ]
- replace_for_html_imports_polyfill = "crisper.js"
-
- deps = [
- ":unpak",
- ]
-}
-
-unpak("unpak") {
- pak_file = extensions_pak_file
- out_folder = unpak_folder
-
- deps = [
- ":flattened_resources",
- ]
-}
-
-grit("flattened_resources") {
- source = "extensions_resources.grd"
-
- # The .grd contains references to generated files.
- source_is_generated = true
-
- defines = chrome_grit_defines
- outputs = [
- "grit/extensions_resources.h",
- "grit/extensions_resources_map.cc",
- "grit/extensions_resources_map.h",
- extensions_pak_file,
- ]
- output_dir = "$root_gen_dir/chrome/browser/resources/extensions"
+if (optimize_webui) {
+ extensions_pak_file = "extensions_resources.pak"
+ unpak_folder = "extensions_resources.unpak"
+
+ optimize_webui("build") {
+ host = "extensions"
+ html_in_files = [ "extensions.html" ]
+ html_out_files = [ "vulcanized.html" ]
+ insert_in_head = "<base href=\"chrome://extensions\">"
+ input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir)
+ js_out_files = [ "crisper.js" ]
+ replace_for_html_imports_polyfill = "crisper.js"
+
+ deps = [
+ ":unpak",
+ ]
+ }
+
+ unpak("unpak") {
+ pak_file = extensions_pak_file
+ out_folder = unpak_folder
+
+ deps = [
+ ":flattened_resources",
+ ]
+ }
+
+ grit("flattened_resources") {
+ source = "extensions_resources.grd"
+
+ # The .grd contains references to generated files.
+ source_is_generated = true
+
+ defines = chrome_grit_defines
+ outputs = [
+ "grit/extensions_resources.h",
+ "grit/extensions_resources_map.cc",
+ "grit/extensions_resources_map.h",
+ extensions_pak_file,
+ ]
+ output_dir = "$root_gen_dir/chrome/browser/resources/extensions"
+ }
}
group("closure_compile") {
@@ -69,6 +71,7 @@ js_type_check("extensions_resources") {
":item_behavior",
":item_list",
":item_util",
+ ":keyboard_shortcut_delegate",
":keyboard_shortcuts",
":kiosk_browser_proxy",
":kiosk_dialog",
@@ -207,9 +210,17 @@ js_library("item_util") {
externs_list = [ "$externs_path/developer_private.js" ]
}
+js_library("keyboard_shortcut_delegate") {
+ deps = [
+ "//ui/webui/resources/js:cr",
+ ]
+ externs_list = [ "$externs_path/developer_private.js" ]
+}
+
js_library("keyboard_shortcuts") {
deps = [
":item_behavior",
+ ":keyboard_shortcut_delegate",
"//ui/webui/resources/cr_elements:cr_container_shadow_behavior",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
@@ -324,6 +335,7 @@ js_library("service") {
deps = [
":error_page",
":item",
+ ":keyboard_shortcut_delegate",
":load_error",
":navigation_helper",
":pack_dialog",
@@ -345,6 +357,7 @@ js_library("service") {
js_library("shortcut_input") {
deps = [
+ ":keyboard_shortcut_delegate",
":shortcut_util",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
diff --git a/chromium/chrome/browser/resources/extensions/detail_view.html b/chromium/chrome/browser/resources/extensions/detail_view.html
index df4e5baf623..23cdc7bc32e 100644
--- a/chromium/chrome/browser/resources/extensions/detail_view.html
+++ b/chromium/chrome/browser/resources/extensions/detail_view.html
@@ -178,7 +178,9 @@
data.type,
'$i18nPolymer{appIcon}',
'$i18nPolymer{extensionIcon}')]]">
- <span id="name" class="cr-title-text">[[data.name]]</span>
+ <span id="name" class="cr-title-text" role="heading" aria-level="1">
+ [[data.name]]
+ </span>
</div>
<div class="section continuation control-line" id="enable-section">
<span class$="[[computeEnabledStyle_(data.state)]]">
@@ -258,17 +260,23 @@
</div>
</div>
<div class="section continuation block">
- <div class="section-title">$i18n{itemDescriptionLabel}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemDescriptionLabel}
+ </div>
<div class="section-content" id="description">
[[getDescription_(data.description, '$i18nPolymer{noDescription}')]]
</div>
</div>
<div class="section block">
- <div class="section-title">$i18n{itemVersion}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemVersion}
+ </div>
<div class="section-content">[[data.version]]</div>
</div>
<div class="section block">
- <div class="section-title">$i18n{itemSize}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemSize}
+ </div>
<div class="section-content" id="size">
<span>[[size_]]</span>
<paper-spinner-lite active="[[!size_]]" hidden="[[size_]]">
@@ -276,12 +284,16 @@
</div>
</div>
<div class="section block" id="id-section" hidden$="[[!inDevMode]]">
- <div class="section-title">$i18n{itemIdHeading}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemIdHeading}
+ </div>
<div class="section-content">[[data.id]]</div>
</div>
<template is="dom-if" if="[[inDevMode]]">
<div class="section block" id="inspectable-views">
- <div class="section-title">$i18n{itemInspectViews}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemInspectViews}
+ </div>
<div class="section-content">
<ul id="inspect-views">
<li hidden="[[data.views.length]]">
@@ -300,7 +312,9 @@
</div>
</template>
<div class="section block">
- <div class="section-title">$i18n{itemPermissions}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemPermissions}
+ </div>
<div class="section-content">
<span id="no-permissions" hidden$="[[hasPermissions_(data.*)]]">
$i18n{itemPermissionsEmpty}
@@ -322,7 +336,9 @@
</div>
</div>
<div class="section block">
- <div class="section-title">$i18n{itemSiteAccess}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemSiteAccess}
+ </div>
<div class="section-content">
<span id="no-site-access"
hidden$="[[showSiteAccessContent_(data.*)]]">
@@ -349,7 +365,9 @@
<template is="dom-if"
if="[[hasDependentExtensions_(data.dependentExtensions.splices)]]">
<div class="section block">
- <div class="section-title">$i18n{itemDependencies}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemDependencies}
+ </div>
<div class="section-content">
<ul id="dependent-extensions-list">
<template is="dom-repeat" items="[[data.dependentExtensions]]">
@@ -405,7 +423,9 @@
id="viewInStore" label="$i18n{viewInStore}"
on-click="onViewInStoreTap_" external></cr-link-row>
<div class="section block">
- <div class="section-title">$i18n{itemSource}</div>
+ <div class="section-title" role="heading" aria-level="2">
+ $i18n{itemSource}
+ </div>
<div id="source" class="section-content">
[[computeSourceString_(data.*)]]
</div>
diff --git a/chromium/chrome/browser/resources/extensions/extensions.html b/chromium/chrome/browser/resources/extensions/extensions.html
index 83ea4fe724a..832434023d9 100644
--- a/chromium/chrome/browser/resources/extensions/extensions.html
+++ b/chromium/chrome/browser/resources/extensions/extensions.html
@@ -61,6 +61,6 @@
</script>
<extensions-manager></extensions-manager>
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
- <link rel="import" href="chrome://extensions/manager.html">
+ <link rel="import" href="manager.html">
</body>
</html>
diff --git a/chromium/chrome/browser/resources/extensions/extensions_resources.grd b/chromium/chrome/browser/resources/extensions/extensions_resources.grd
index 1bb6baea7c5..9201c338087 100644
--- a/chromium/chrome/browser/resources/extensions/extensions_resources.grd
+++ b/chromium/chrome/browser/resources/extensions/extensions_resources.grd
@@ -85,6 +85,12 @@
<structure name="IDR_EXTENSIONS_ERROR_PAGE_JS"
file="error_page.js"
type="chrome_html" />
+ <structure name="IDR_EXTENSIONS_KEYBOARD_SHORTCUT_DELEGATE_HTML"
+ file="keyboard_shortcut_delegate.html"
+ type="chrome_html" />
+ <structure name="IDR_EXTENSIONS_KEYBOARD_SHORTCUT_DELEGATE_JS"
+ file="keyboard_shortcut_delegate.js"
+ type="chrome_html" />
<structure name="IDR_EXTENSIONS_KEYBOARD_SHORTCUTS_HTML"
file="keyboard_shortcuts.html"
type="chrome_html" />
diff --git a/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.html b/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.html
new file mode 100644
index 00000000000..bb851cf9c59
--- /dev/null
+++ b/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.html
@@ -0,0 +1 @@
+<script src="keyboard_shortcut_delegate.js"></script>
diff --git a/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.js b/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.js
new file mode 100644
index 00000000000..d83e47926d3
--- /dev/null
+++ b/chromium/chrome/browser/resources/extensions/keyboard_shortcut_delegate.js
@@ -0,0 +1,41 @@
+// 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.
+
+cr.define('extensions', function() {
+ 'use strict';
+
+ /** @interface */
+ class KeyboardShortcutDelegate {
+ /**
+ * Called when shortcut capturing changes in order to suspend or re-enable
+ * global shortcut handling. This is important so that the shortcuts aren't
+ * processed normally as the user types them.
+ * TODO(devlin): From very brief experimentation, it looks like preventing
+ * the default handling on the event also does this. Investigate more in the
+ * future.
+ * @param {boolean} isCapturing
+ */
+ setShortcutHandlingSuspended(isCapturing) {}
+
+ /**
+ * Updates an extension command's keybinding.
+ * @param {string} extensionId
+ * @param {string} commandName
+ * @param {string} keybinding
+ */
+ updateExtensionCommandKeybinding(extensionId, commandName, keybinding) {}
+
+ /**
+ * Updates an extension command's scope.
+ * @param {string} extensionId
+ * @param {string} commandName
+ * @param {chrome.developerPrivate.CommandScope} scope
+ */
+ updateExtensionCommandScope(extensionId, commandName, scope) {}
+ }
+
+ return {
+ KeyboardShortcutDelegate: KeyboardShortcutDelegate,
+ };
+});
diff --git a/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.html b/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.html
index 73968d69f68..cc985093d80 100644
--- a/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.html
+++ b/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.html
@@ -7,6 +7,7 @@
<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
<link rel="import" href="item_behavior.html">
+<link rel="import" href="keyboard_shortcut_delegate.html">
<link rel="import" href="shortcut_input.html">
<dom-module id="extensions-keyboard-shortcuts">
diff --git a/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.js b/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.js
index c740d566ea3..f0716526957 100644
--- a/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.js
+++ b/chromium/chrome/browser/resources/extensions/keyboard_shortcuts.js
@@ -5,36 +5,6 @@
cr.define('extensions', function() {
'use strict';
- /** @interface */
- class KeyboardShortcutDelegate {
- /**
- * Called when shortcut capturing changes in order to suspend or re-enable
- * global shortcut handling. This is important so that the shortcuts aren't
- * processed normally as the user types them.
- * TODO(devlin): From very brief experimentation, it looks like preventing
- * the default handling on the event also does this. Investigate more in the
- * future.
- * @param {boolean} isCapturing
- */
- setShortcutHandlingSuspended(isCapturing) {}
-
- /**
- * Updates an extension command's keybinding.
- * @param {string} extensionId
- * @param {string} commandName
- * @param {string} keybinding
- */
- updateExtensionCommandKeybinding(extensionId, commandName, keybinding) {}
-
- /**
- * Updates an extension command's scope.
- * @param {string} extensionId
- * @param {string} commandName
- * @param {chrome.developerPrivate.CommandScope} scope
- */
- updateExtensionCommandScope(extensionId, commandName, scope) {}
- }
-
// The UI to display and manage keyboard shortcuts set for extension commands.
const KeyboardShortcuts = Polymer({
is: 'extensions-keyboard-shortcuts',
@@ -127,7 +97,6 @@ cr.define('extensions', function() {
});
return {
- KeyboardShortcutDelegate: KeyboardShortcutDelegate,
KeyboardShortcuts: KeyboardShortcuts,
};
});
diff --git a/chromium/chrome/browser/resources/extensions/toolbar.html b/chromium/chrome/browser/resources/extensions/toolbar.html
index 9b8706bd762..38cf1124e61 100644
--- a/chromium/chrome/browser/resources/extensions/toolbar.html
+++ b/chromium/chrome/browser/resources/extensions/toolbar.html
@@ -97,10 +97,11 @@
narrow-threshold="1000">
<div class="more-actions">
<span id="devModeLabel">$i18n{toolbarDevMode}</span>
- <cr-tooltip-icon hidden$="[[!devModeControlledByPolicy]]"
- tooltip-text="$i18n{controlledSettingPolicy}"
- icon-class="cr20:domain"
- icon-aria-label="$i18n{controlledSettingPolicy}">
+ <cr-tooltip-icon hidden="[[!shouldDisableDevMode_(
+ devModeControlledByPolicy, isSupervised)]]"
+ tooltip-text="[[getTooltipText_(isSupervised)]]"
+ icon-class="[[getIcon_(isSupervised)]]"
+ icon-aria-label="[[getTooltipText_(isSupervised)]]">
</cr-tooltip-icon>
<cr-toggle id="devMode" on-change="onDevModeToggleChange_"
disabled="[[shouldDisableDevMode_(
diff --git a/chromium/chrome/browser/resources/extensions/toolbar.js b/chromium/chrome/browser/resources/extensions/toolbar.js
index bd3590edcba..228cc45667d 100644
--- a/chromium/chrome/browser/resources/extensions/toolbar.js
+++ b/chromium/chrome/browser/resources/extensions/toolbar.js
@@ -76,6 +76,24 @@ cr.define('extensions', function() {
},
/**
+ * @return {string}
+ * @private
+ */
+ getTooltipText_: function() {
+ return this.i18n(
+ this.isSupervised ? 'controlledSettingChildRestriction' :
+ 'controlledSettingPolicy');
+ },
+
+ /**
+ * @return {string}
+ * @private
+ */
+ getIcon_: function() {
+ return this.isSupervised ? 'cr20:kite' : 'cr20:domain';
+ },
+
+ /**
* @param {!CustomEvent<boolean>} e
* @private
*/
diff --git a/chromium/chrome/browser/resources/feedback/html/default.html b/chromium/chrome/browser/resources/feedback/html/default.html
index 4443627fb7e..c2e2f2782b5 100644
--- a/chromium/chrome/browser/resources/feedback/html/default.html
+++ b/chromium/chrome/browser/resources/feedback/html/default.html
@@ -47,13 +47,14 @@
<!-- Attach a file -->
<div id="attach-file-container" class="text-field-container">
<label id="attach-file-label" i18n-content="attach-file-label"></label>
- <input id="attach-file" type="file" aria-labelledby="attach-file-label">
+ <input id="attach-file" type="file" aria-labelledby="attach-file-label"
+ aria-describedby="attach-file-note">
<div id="custom-file-container" hidden>
<label id="attached-filename-text"></label>
<button id="remove-attached-file" class="remove-file-button"></button>
</div>
<div id="attach-error" class="attach-file-notification"
- i18n-content="attach-file-to-big" hidden></div>
+ role="alert" i18n-content="attach-file-to-big" hidden></div>
</div>
<div id="attach-file-note" i18n-content="attach-file-note"></div>
<!-- Screenshot -->
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
index 7161b0893c1..6881172f6dc 100644
--- a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -241,6 +241,7 @@ cr.define('cr.login', function() {
this.confirmPasswordCallback = null;
this.noPasswordCallback = null;
+ this.onePasswordCallback = null;
this.insecureContentBlockedCallback = null;
this.samlApiUsedCallback = null;
this.missingGaiaInfoCallback = null;
@@ -848,7 +849,9 @@ cr.define('cr.login', function() {
if (this.samlHandler_.samlApiUsed) {
if (this.samlApiUsedCallback) {
- this.samlApiUsedCallback();
+ // Makes distinction between Gaia and Chrome Credentials Passing API
+ // login to properly fill ChromeOS.SAML.ApiLogin metrics.
+ this.samlApiUsedCallback(this.authFlow == AuthFlow.SAML);
}
this.password_ = this.samlHandler_.apiPasswordBytes;
this.onAuthCompleted_();
@@ -870,6 +873,9 @@ cr.define('cr.login', function() {
// If we scraped exactly one password, we complete the
// authentication right away.
this.password_ = this.samlHandler_.firstScrapedPassword;
+ if (this.onePasswordCallback) {
+ this.onePasswordCallback();
+ }
this.onAuthCompleted_();
return;
}
@@ -888,8 +894,8 @@ cr.define('cr.login', function() {
/**
* Invoked to complete the authentication using the password the user
- * enters manually for non-principals API SAML IdPs that we couldn't
- * scrape their password input.
+ * enters manually for SAML IdPs that do not use Chrome Credentials Passing
+ * API and we couldn't scrape their password input.
*/
completeAuthWithManualPassword(password) {
this.password_ = password;
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js b/chromium/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js
new file mode 100644
index 00000000000..d2b13e7c2bc
--- /dev/null
+++ b/chromium/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js
@@ -0,0 +1,58 @@
+// 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.
+
+/**
+ * Intercept Ajax responses, detect responses to the password-change endpoint
+ * that don't contain any errors.
+ */
+(function() {
+function oktaDetectSuccess() {
+ const PARENT_ORIGIN = 'chrome://password-change';
+
+ let messageFromParent;
+ function onMessageReceived(event) {
+ if (event.origin == PARENT_ORIGIN) {
+ messageFromParent = event;
+ }
+ }
+ window.addEventListener('message', onMessageReceived, false);
+
+ function checkResponse(responseUrl, responseData) {
+ if (responseUrl.includes('/internal_login/password') &&
+ !responseData.match(/"has[A-Za-z]*Errors":true/)) {
+ console.info('passwordChangeSuccess');
+ messageFromParent.source.postMessage(
+ 'passwordChangeSuccess', PARENT_ORIGIN);
+ }
+ }
+
+ const proxied = window.XMLHttpRequest.prototype.send;
+
+ window.XMLHttpRequest.prototype.send = function() {
+ this.addEventListener('load', function() {
+ checkResponse(this.responseURL, this.response);
+ });
+ return proxied.apply(this, arguments);
+ };
+}
+
+/** Run a script in the window context - not isolated as a content-script. */
+function runInPageContext(jsFn) {
+ const script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.innerHTML = '(' + jsFn + ')();';
+ document.head.prepend(script);
+}
+
+/** Wait until DOM is loaded, then run oktaDetectSuccess script. */
+function initialize() {
+ if (document.body && document.head) {
+ console.info('initialize');
+ runInPageContext(oktaDetectSuccess);
+ } else {
+ requestIdleCallback(initialize);
+ }
+}
+requestIdleCallback(initialize);
+})();
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
index 0f5fa464c5f..7854c1b20cb 100644
--- a/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
+++ b/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
@@ -12,9 +12,105 @@
cr.define('cr.samlPasswordChange', function() {
'use strict';
+ /** @const */
+ const oktaInjectedScriptName = 'oktaInjected';
+
+ /**
+ * The script to inject into Okta user settings page.
+ * @type {string}
+ */
+ const oktaInjectedJs = String.raw`
+ // <include src="okta_detect_success_injected.js">
+ `;
+
const BLANK_PAGE_URL = 'about:blank';
/**
+ * The different providers of password-change pages that we support, or are
+ * working on supporting.
+ * @enum {number}
+ */
+ const PasswordChangePageProvider = {
+ UNKNOWN: 0,
+ ADFS: 1,
+ AZURE: 2,
+ OKTA: 3,
+ PING: 4,
+ };
+
+ /**
+ * @param {URL?} url The url of the webpage that is being interacted with.
+ * @return {PasswordChangePageProvider} The provider of the password change
+ * page, as detected based on the URL.
+ */
+ function detectProvider_(url) {
+ if (!url) {
+ return null;
+ }
+ if (url.pathname.match(/\/updatepassword\/?$/)) {
+ return PasswordChangePageProvider.ADFS;
+ }
+ if (url.pathname.endsWith('/ChangePassword.aspx')) {
+ return PasswordChangePageProvider.AZURE;
+ }
+ if (url.host.match(/\.okta\.com$/)) {
+ return PasswordChangePageProvider.OKTA;
+ }
+ if (url.pathname.match('/password/chg/')) {
+ return PasswordChangePageProvider.PING;
+ }
+ return PasswordChangePageProvider.UNKNOWN;
+ }
+
+ /**
+ * @param {string?} str A string that should be a valid URL.
+ * @return {URL?} A valid URL object, or null.
+ */
+ function safeParseUrl_(str) {
+ try {
+ return new URL(str);
+ } catch (error) {
+ console.error('Invalid url: ' + str);
+ return null;
+ }
+ }
+
+ /**
+ * @param {Object} details The web-request details.
+ * @return {boolean} True if we detect that a password change was successful.
+ */
+ function detectPasswordChangeSuccess(details) {
+ const url = safeParseUrl_(details.url);
+ if (!url) {
+ return false;
+ }
+
+ // We count it as a success whenever "status=0" is in the query params.
+ // This is what we use for ADFS, but for now, we allow it for every IdP, so
+ // that an otherwise unsupported IdP can also send it as a success message.
+ // TODO(https://crbug.com/930109): Consider removing this entirely, or,
+ // using a more self-documenting parameter like 'passwordChanged=1'.
+ if (url.searchParams.get('status') == '0') {
+ return true;
+ }
+
+ const pageProvider = detectProvider_(url);
+ // These heuristics work for the following SAML IdPs:
+ if (pageProvider == PasswordChangePageProvider.ADFS) {
+ return url.searchParams.get('status') == '0';
+ }
+ if (pageProvider == PasswordChangePageProvider.AZURE) {
+ return url.searchParams.get('ReturnCode') == '0';
+ }
+
+ // We can't currently detect success for Okta or Ping just by inspecting the
+ // URL or even response headers. To inspect the response body, we need
+ // to inject scripts onto their page (see okta_detect_success_injected.js).
+
+ return false;
+ }
+
+ /**
* Initializes the authenticator component.
*/
class Authenticator extends cr.EventTarget {
@@ -67,8 +163,27 @@ cr.define('cr.samlPasswordChange', function() {
this.samlHandler_, 'authPageLoaded',
this.onAuthPageLoaded_.bind(this));
+ // Listen for completed main-frame requests to check for password-change
+ // success.
+ this.webviewEventManager_.addWebRequestEventListener(
+ this.webview_.request.onCompleted,
+ this.onCompleted_.bind(this),
+ {urls: ['*://*/*'], types: ['main_frame']},
+ );
+
+ // Inject a custom script for detecting password change success in Okta.
+ this.webview_.addContentScripts([{
+ name: oktaInjectedScriptName,
+ matches: ['*://*.okta.com/*'],
+ js: {code: oktaInjectedJs},
+ all_frames: true,
+ run_at: 'document_start'
+ }]);
+
+ // Okta-detect-success-inject script signals success by posting a message
+ // that says "passwordChangeSuccess", which we listen for:
this.webviewEventManager_.addEventListener(
- this.webview_, 'contentload', this.onContentLoad_.bind(this));
+ window, 'message', this.onMessageReceived_.bind(this));
}
/**
@@ -129,7 +244,7 @@ cr.define('cr.samlPasswordChange', function() {
* Sends scraped password and resets the state.
* @private
*/
- completeAuth_() {
+ onPasswordChangeSuccess_() {
const passwordsOnce = this.samlHandler_.getPasswordsScrapedTimes(1);
const passwordsTwice = this.samlHandler_.getPasswordsScrapedTimes(2);
@@ -151,17 +266,43 @@ cr.define('cr.samlPasswordChange', function() {
}
/**
- * Invoked when a new document is loaded.
+ * Invoked when a new document loading completes.
+ * @param {Object} details The web-request details.
* @private
*/
- onContentLoad_(e) {
- const currentUrl = this.webview_.src;
- // TODO(rsorokin): Implement more robust check.
- if (currentUrl.lastIndexOf('status=0') != -1) {
- this.completeAuth_();
+ onCompleted_(details) {
+ if (detectPasswordChangeSuccess(details)) {
+ this.onPasswordChangeSuccess_();
+ }
+
+ // Okta_detect_success_injected.js needs to be contacted by the parent,
+ // so that it can send messages back to the parent.
+ const pageProvider = detectProvider_(safeParseUrl_(details.url));
+ if (pageProvider == PasswordChangePageProvider.OKTA) {
+ // Using setTimeout gives the page time to finish initializing.
+ setTimeout(() => {
+ this.webview_.contentWindow.postMessage('connect', details.url);
+ }, 1000);
+ }
+ }
+
+ /**
+ * Invoked when the webview posts a message.
+ * @param {Object} event The message event.
+ * @private
+ */
+ onMessageReceived_(event) {
+ if (event.data == 'passwordChangeSuccess') {
+ const pageProvider = detectProvider_(safeParseUrl_(event.origin));
+ if (pageProvider == PasswordChangePageProvider.OKTA) {
+ this.onPasswordChangeSuccess_();
+ }
}
}
}
- return {Authenticator: Authenticator};
+ return {
+ Authenticator: Authenticator,
+ detectPasswordChangeSuccess: detectPasswordChangeSuccess,
+ };
});
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator_test.unitjs b/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator_test.unitjs
new file mode 100644
index 00000000000..617677b55ee
--- /dev/null
+++ b/chromium/chrome/browser/resources/gaia_auth_host/password_change_authenticator_test.unitjs
@@ -0,0 +1,76 @@
+// 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.
+
+GEN_INCLUDE(['//ui/webui/resources/js/cr.js']);
+
+const EXAMPLE_ADFS_ENDPOINT =
+ 'https://example.com/adfs/portal/updatepassword/';
+
+const EXAMPLE_AZURE_ENDPOINT =
+ 'https://example.windowsazure.com/ChangePassword.aspx';
+
+const EXAMPLE_OKTA_ENDPOINT =
+ 'https://example.okta.com/user/profile/internal_login/password';
+
+const EXAMPLE_PING_ENDPOINT =
+ 'https://login.pingone.com/idp/directory/a/12345/password/chg/67890';
+
+PasswordChangeAuthenticatorUnitTest = class extends testing.Test {
+ get browsePreload() {
+ return DUMMY_URL;
+ }
+
+ // No need to run these checks - see comment in SamlPasswordAttributesTest.
+ get runAccessibilityChecks() {
+ return false;
+ }
+
+ get extraLibraries() {
+ return [
+ '//ui/webui/resources/js/cr/event_target.js',
+ 'password_change_authenticator.js',
+ ];
+ }
+
+ assertSuccess(details) {
+ assertTrue(this.detectSuccess(details));
+ }
+
+ assertNotSuccess(details, responseData) {
+ assertFalse(this.detectSuccess(details));
+ }
+
+ detectSuccess(details) {
+ if (typeof details == 'string') {
+ details = {'url': details};
+ }
+ return cr.samlPasswordChange.detectPasswordChangeSuccess(details);
+ }
+}
+
+TEST_F('PasswordChangeAuthenticatorUnitTest', 'DetectAdfsSuccess', function() {
+ const endpointUrl = EXAMPLE_ADFS_ENDPOINT;
+
+ this.assertNotSuccess(endpointUrl);
+ this.assertNotSuccess(endpointUrl + '?status=1');
+ this.assertSuccess(endpointUrl + '?status=0');
+
+ // We allow "status=0" to count as success everywhere right now, but this
+ // should be narrowed down to ADFS - see the TODO in the code.
+ this.assertSuccess(EXAMPLE_AZURE_ENDPOINT + '?status=0');
+});
+
+TEST_F('PasswordChangeAuthenticatorUnitTest', 'DetectAzureSuccess', function() {
+ const endpointUrl = EXAMPLE_AZURE_ENDPOINT;
+ const extraParam = 'BrandContextID=O123';
+
+ this.assertNotSuccess(endpointUrl);
+ this.assertNotSuccess(endpointUrl + '?' + extraParam);
+ this.assertNotSuccess(endpointUrl + '?ReturnCode=1&' + extraParam);
+ this.assertNotSuccess(endpointUrl + '?' + extraParam + '&ReturnCode=1');
+ this.assertNotSuccess(EXAMPLE_PING_ENDPOINT + '?ReturnCode=0');
+
+ this.assertSuccess(endpointUrl + '?ReturnCode=0&' + extraParam);
+ this.assertSuccess(endpointUrl + '?' + extraParam + '&ReturnCode=0');
+}); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/hangout_services/OWNERS b/chromium/chrome/browser/resources/hangout_services/OWNERS
index db6c6c297e3..f283b346811 100644
--- a/chromium/chrome/browser/resources/hangout_services/OWNERS
+++ b/chromium/chrome/browser/resources/hangout_services/OWNERS
@@ -1,2 +1,2 @@
-bemasc@chromium.org
+eladalon@chromium.org
grunell@chromium.org
diff --git a/chromium/chrome/browser/resources/hats/hats.html b/chromium/chrome/browser/resources/hats/hats.html
index 18ec74d79e5..9c17d2a6fa8 100644
--- a/chromium/chrome/browser/resources/hats/hats.html
+++ b/chromium/chrome/browser/resources/hats/hats.html
@@ -16,6 +16,13 @@
/* Needs to override dynamically loaded, more specific styles. */
outline-color: rgb(77, 144, 254) !important;
}
+ /* Make sure scroll bars are added only when necessary, the overriden
+ * value is 'scroll' which causes scroll bars always show.
+ * TODO(weili): Remove this once the overriden value changed to auto.
+ */
+ #t402-prompt.t402-prompt-websat-modal {
+ overflow: auto !important;
+ }
</style>
<script>
/**
diff --git a/chromium/chrome/browser/resources/history/BUILD.gn b/chromium/chrome/browser/resources/history/BUILD.gn
index 7bf036c5332..042656ba371 100644
--- a/chromium/chrome/browser/resources/history/BUILD.gn
+++ b/chromium/chrome/browser/resources/history/BUILD.gn
@@ -87,6 +87,7 @@ js_library("history_list") {
"//third_party/polymer/v1_0/components-chromium/iron-scroll-threshold:iron-scroll-threshold-extracted",
"//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
"//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render",
+ "//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:util",
]
diff --git a/chromium/chrome/browser/resources/history/history_list.html b/chromium/chrome/browser/resources/history/history_list.html
index cbd4f20d146..01e555cf217 100644
--- a/chromium/chrome/browser/resources/history/history_list.html
+++ b/chromium/chrome/browser/resources/history/history_list.html
@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
<link rel="import" href="chrome://resources/cr_elements/shared_style_css.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-list/iron-list.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-threshold/iron-scroll-threshold.html">
diff --git a/chromium/chrome/browser/resources/history/history_list.js b/chromium/chrome/browser/resources/history/history_list.js
index 18805d54ef2..35b256e2fab 100644
--- a/chromium/chrome/browser/resources/history/history_list.js
+++ b/chromium/chrome/browser/resources/history/history_list.js
@@ -5,6 +5,8 @@
Polymer({
is: 'history-list',
+ behaviors: [I18nBehavior],
+
properties: {
// The search term for the current query. Set when the query returns.
searchedTerm: {
@@ -60,6 +62,10 @@ Polymer({
actionMenuModel_: Object,
},
+ hostAttributes: {
+ role: 'application',
+ },
+
listeners: {
'history-checkbox-select': 'onItemSelected_',
'open-menu': 'onOpenMenu_',
@@ -74,6 +80,7 @@ Polymer({
/** @type {IronListElement} */ (this.$['infinite-list']).notifyResize();
this.$['infinite-list'].scrollTarget = this;
this.$['scroll-threshold'].scrollTarget = this;
+ this.setAttribute('aria-roledescription', this.i18n('ariaRoleDescription'));
},
/////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/chrome/browser/resources/identity_internals/identity_internals.js b/chromium/chrome/browser/resources/identity_internals/identity_internals.js
index 23cb35553cf..76de89b9d71 100644
--- a/chromium/chrome/browser/resources/identity_internals/identity_internals.js
+++ b/chromium/chrome/browser/resources/identity_internals/identity_internals.js
@@ -11,7 +11,7 @@ cr.define('identity_internals', function() {
* @constructor
*/
function TokenListItem(tokenInfo) {
- const el = cr.doc.createElement('div');
+ const el = document.createElement('div');
el.data_ = tokenInfo;
el.__proto__ = TokenListItem.prototype;
el.decorate();
diff --git a/chromium/chrome/browser/resources/inline_login/inline_login.html b/chromium/chrome/browser/resources/inline_login/inline_login.html
index 3bc61db7ddc..ba073cef263 100644
--- a/chromium/chrome/browser/resources/inline_login/inline_login.html
+++ b/chromium/chrome/browser/resources/inline_login/inline_login.html
@@ -1,6 +1,7 @@
<!doctype html>
<html dir="$i18n{textdirection}" lang="$i18n{language}">
<head>
+ <meta charset="utf-8">
<title>$i18n{title}</title>
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
diff --git a/chromium/chrome/browser/resources/local_ntp/customize.css b/chromium/chrome/browser/resources/local_ntp/customize.css
index ec345861118..b860452291c 100644
--- a/chromium/chrome/browser/resources/local_ntp/customize.css
+++ b/chromium/chrome/browser/resources/local_ntp/customize.css
@@ -665,8 +665,7 @@ html[dir=rtl] .selected-check {
color: white;
font-weight: 500;
left: 16px;
- max-width: 80%;
- padding: 8px 8px 8px 8px;
+ padding: 8px;
position: fixed;
text-shadow: 0 0 16px rgba(0, 0, 0, .3);
z-index: -1;
@@ -678,18 +677,30 @@ html[dir=rtl] #custom-bg-attr {
right: 16px;
}
-.attr-common {
+#custom-bg-attr a {
+ clear: both;
+ color: inherit;
+ float: left;
font-size: 13px;
height: 20px;
line-height: 20px;
+ max-width: 50vw;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
- width: -webkit-fill-available;
}
-.attr-common.attr-small {
+[dir=rtl] #custom-bg-attr a {
+ float: right;
+}
+
+#custom-bg-attr a[href=''] {
+ cursor: auto;
+ text-decoration: none;
+}
+
+#custom-bg-attr a ~ a {
font-size: 11px;
}
@@ -697,11 +708,6 @@ html[dir=rtl] #custom-bg-attr {
background: rgba(var(--GG900-rgb), .1);
}
-.attr-link {
- display: inline-block;
- text-decoration: underline;
-}
-
#link-icon {
background: url(icons/link.svg);
background-size: 10px 10px;
diff --git a/chromium/chrome/browser/resources/local_ntp/customize.js b/chromium/chrome/browser/resources/local_ntp/customize.js
index ce243db2718..487827f5bed 100644
--- a/chromium/chrome/browser/resources/local_ntp/customize.js
+++ b/chromium/chrome/browser/resources/local_ntp/customize.js
@@ -163,7 +163,6 @@ customize.IDS = {
*/
customize.CLASSES = {
ATTR_SMALL: 'attr-small',
- ATTR_COMMON: 'attr-common',
ATTR_LINK: 'attr-link',
COLLECTION_DIALOG: 'is-col-sel',
COLLECTION_SELECTED: 'bg-selected', // Highlight selected tile
@@ -358,25 +357,27 @@ customize.onThemeChange = function() {
customize.setAttribution = function(
attributionLine1, attributionLine2, attributionActionUrl) {
const attributionBox = $(customize.IDS.ATTRIBUTIONS);
- const attr1 = document.createElement('span');
+ const attr1 = document.createElement('a');
attr1.id = customize.IDS.ATTR1;
- const attr2 = document.createElement('span');
+ const attr2 = document.createElement('a');
attr2.id = customize.IDS.ATTR2;
if (attributionLine1 !== '') {
// Shouldn't be changed from textContent for security assurances.
attr1.textContent = attributionLine1;
- attr1.classList.add(customize.CLASSES.ATTR_COMMON);
+ attr1.href = attributionActionUrl || '';
$(customize.IDS.ATTRIBUTIONS).appendChild(attr1);
}
+
if (attributionLine2 !== '') {
// Shouldn't be changed from textContent for security assurances.
attr2.textContent = attributionLine2;
- attr2.classList.add(customize.CLASSES.ATTR_SMALL);
- attr2.classList.add(customize.CLASSES.ATTR_COMMON);
+ attr2.href = attributionActionUrl || '';
attributionBox.appendChild(attr2);
}
- if (attributionActionUrl !== '') {
+
+ const hasActionUrl = attributionActionUrl !== '';
+ if (hasActionUrl) {
const attr = (attributionLine2 !== '' ? attr2 : attr1);
attr.classList.add(customize.CLASSES.ATTR_LINK);
@@ -388,24 +389,18 @@ customize.setAttribution = function(
}
attr.insertBefore(linkIcon, attr.firstChild);
- attributionBox.classList.add(customize.CLASSES.ATTR_LINK);
- attributionBox.href = attributionActionUrl;
- attributionBox.onclick = function() {
- ntpApiHandle.logEvent(
- customize.LOG_TYPE.NTP_CUSTOMIZE_ATTRIBUTION_CLICKED);
+ attributionBox.onclick = e => {
+ if (attr1.contains(e.target) || attr2.contains(e.target)) {
+ ntpApiHandle.logEvent(
+ customize.LOG_TYPE.NTP_CUSTOMIZE_ATTRIBUTION_CLICKED);
+ }
};
- attributionBox.style.cursor = 'pointer';
}
+ attributionBox.classList.toggle(customize.CLASSES.ATTR_LINK, hasActionUrl);
};
customize.clearAttribution = function() {
- const attributions = $(customize.IDS.ATTRIBUTIONS);
- attributions.removeAttribute('href');
- attributions.className = '';
- attributions.style.cursor = 'default';
- while (attributions.firstChild) {
- attributions.removeChild(attributions.firstChild);
- }
+ $(customize.IDS.ATTRIBUTIONS).innerHTML = '';
};
customize.unselectTile = function() {
@@ -765,6 +760,7 @@ customize.showCollectionSelectionDialog = function() {
$(customize.IDS.BACKGROUNDS_MENU) :
$(customize.IDS.TILES);
if (configData.richerPicker && customize.builtTiles) {
+ tileContainer.focus();
return;
}
customize.builtTiles = true;
@@ -855,7 +851,7 @@ customize.showCollectionSelectionDialog = function() {
$(customize.IDS.BACKGROUNDS_DEFAULT_ICON).onClickOverride =
$(customize.IDS.BACKGROUNDS_DEFAULT).onkeydown;
- $(customize.IDS.TILES).focus();
+ tileContainer.focus();
};
/**
@@ -929,7 +925,7 @@ customize.richerPicker_previewImage = function(tile) {
if (tile.id === customize.IDS.BACKGROUNDS_DEFAULT_ICON) {
preview.dataset.hasImage = false;
preview.style.backgroundImage = '';
- preview.style.backgroundColor = document.body.style.backgroundColor;
+ preview.style.backgroundColor = 'transparent';
} else if (tile.id === customize.IDS.BACKGROUNDS_UPLOAD_ICON) {
// No previews for uploaded images.
return;
@@ -939,6 +935,9 @@ customize.richerPicker_previewImage = function(tile) {
const re = /w\d+\-h\d+/;
preview.style.backgroundImage =
tile.style.backgroundImage.replace(re, 'w1280-h720');
+ preview.dataset.attributionLine1 = tile.dataset.attributionLine1;
+ preview.dataset.attributionLine2 = tile.dataset.attributionLine2;
+ preview.dataset.attributionActionUrl = tile.dataset.attributionActionUrl;
}
background.style.opacity = 0;
preview.style.opacity = 1;
@@ -1393,10 +1392,7 @@ customize.richerPicker_resetSelectedOptions = function() {
customize.selectedOptions.background = null;
customize.selectedOptions.backgroundData = null;
- // Reset color selection.
- customize.richerPicker_removeSelectedState(customize.selectedOptions.color);
- customize.selectedOptions.color = null;
- customize.preselectedOptions.colorsMenuTile = null;
+ customize.resetColorsSelectedOptions();
customize.richerPicker_preselectShortcutOptions();
};
@@ -1461,7 +1457,7 @@ customize.richerPicker_resetCustomizationMenu = function() {
customize.richerPicker_resetSelectedOptions();
customize.richerPicker_resetImageMenu();
customize.richerPicker_hideOpenSubmenu();
- customize.resetColorsMenu();
+ customize.resetColorPicker();
};
/**
@@ -1522,7 +1518,6 @@ customize.richerPicker_applyCustomization = function() {
customize.init = function(showErrorNotification, hideCustomLinkNotification) {
ntpApiHandle = window.chrome.embeddedSearch.newTabPage;
const editDialog = $(customize.IDS.EDIT_BG_DIALOG);
- const menu = $(customize.IDS.MENU);
$(customize.IDS.OPTIONS_TITLE).textContent =
configData.translatedStrings.customizeThisPage;
@@ -1557,6 +1552,8 @@ customize.init = function(showErrorNotification, hideCustomLinkNotification) {
}
};
$(customize.IDS.EDIT_BG).onclick = function(event) {
+ $(customize.IDS.CUSTOMIZATION_MENU)
+ .classList.add(customize.CLASSES.MOUSE_NAV);
editDialog.classList.add(customize.CLASSES.MOUSE_NAV);
editBackgroundInteraction();
};
@@ -1982,7 +1979,9 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
richerPicker.classList.add(customize.CLASSES.MOUSE_NAV);
};
richerPicker.onkeydown = function(event) {
- richerPicker.classList.remove(customize.CLASSES.MOUSE_NAV);
+ if (Object.values(customize.KEYCODES).includes(event.keyCode)) {
+ richerPicker.classList.remove(customize.CLASSES.MOUSE_NAV);
+ }
if (event.keyCode === customize.KEYCODES.BACKSPACE &&
customize.richerPicker_selectedSubmenu.menu.id ===
@@ -2040,6 +2039,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
+ richerPicker.classList.remove(customize.CLASSES.MOUSE_NAV);
if (event.keyCode === forwardArrowKey) {
mvOption.focus();
} else if (event.keyCode === customize.KEYCODES.DOWN) {
@@ -2068,6 +2068,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
+ richerPicker.classList.remove(customize.CLASSES.MOUSE_NAV);
if (event.keyCode === backArrowKey) {
clOption.focus();
} else if (
@@ -2094,6 +2095,7 @@ customize.initCustomBackgrounds = function(showErrorNotification) {
// Handle arrow key navigation.
event.preventDefault();
event.stopPropagation();
+ richerPicker.classList.remove(customize.CLASSES.MOUSE_NAV);
if (event.keyCode === backArrowKey ||
event.keyCode === customize.KEYCODES.UP) {
mvOption.focus();
@@ -2204,11 +2206,11 @@ customize.updateColorsMenuTileSelection = function(tile) {
*/
customize.colorTileInteraction = function(event) {
customize.updateColorsMenuTileSelection(
- /** @type HTMLElement */ (event.target));
- const id = parseInt(event.target.dataset.id, 10);
+ /** @type HTMLElement */ (event.currentTarget));
+ const id = parseInt(event.currentTarget.dataset.id, 10);
if (id) {
ntpApiHandle.applyAutogeneratedTheme(
- id, event.target.dataset.color.split(','));
+ id, event.currentTarget.dataset.color.split(','));
}
};
@@ -2219,7 +2221,7 @@ customize.colorTileInteraction = function(event) {
*/
customize.defaultThemeTileInteraction = function(event) {
customize.updateColorsMenuTileSelection(
- /** @type HTMLElement */ (event.target));
+ /** @type HTMLElement */ (event.currentTarget));
ntpApiHandle.applyDefaultTheme();
};
@@ -2229,7 +2231,7 @@ customize.defaultThemeTileInteraction = function(event) {
* @param {Event} event The event attributes for the interaction.
*/
customize.colorPickerTileInteraction = function(event) {
- const hex = event.target.value;
+ const hex = event.currentTarget.value;
const r = parseInt(hex.substring(1, 3), 16);
const g = parseInt(hex.substring(3, 5), 16);
const b = parseInt(hex.substring(5, 7), 16);
@@ -2244,14 +2246,22 @@ customize.colorPickerTileInteraction = function(event) {
};
/**
- * Loads Colors menu elements.
+ * Loads Colors menu elements and initializes the selected state.
*/
customize.loadColorsMenu = function() {
- if (customize.colorsMenuLoaded) {
- customize.colorsMenuPreselectTile();
- return;
+ if (!customize.colorsMenuLoaded) {
+ customize.loadColorMenuTiles();
+ customize.colorsMenuLoaded = true;
}
+ customize.resetColorsSelectedOptions();
+ customize.colorsMenuOnThemeChange();
+};
+
+/**
+ * Loads Colors menu tiles, e.g. color picker, default tile and color tiles.
+ */
+customize.loadColorMenuTiles = function() {
const colorsColl = ntpApiHandle.getColorsInfo();
for (let i = 0; i < colorsColl.length; ++i) {
// After 4 color tiles create an empty tile to take the place of the color
@@ -2303,15 +2313,11 @@ customize.loadColorsMenu = function() {
$(customize.IDS.COLOR_PICKER).onchange =
customize.colorPickerTileInteraction;
}
-
- customize.colorsMenuOnThemeChange();
-
- customize.colorsMenuLoaded = true;
};
/**
- * Update webstore theme info and preselect Colors menu tile according to the
- * theme update.
+ * Update webstore theme info and preselect Colors menu tile according to
+ * the theme update.
*/
customize.colorsMenuOnThemeChange = function() {
// Update webstore theme information.
@@ -2330,6 +2336,10 @@ customize.colorsMenuOnThemeChange = function() {
customize.selectedOptions.color);
customize.selectedOptions.color = null;
}
+ if (!customize.preselectedOptions.colorsMenuTile) {
+ customize.preselectedOptions.colorsMenuTile =
+ $(customize.IDS.COLORS_THEME);
+ }
} else {
$(customize.IDS.COLORS_THEME).classList.remove(customize.CLASSES.VISIBLE);
@@ -2343,7 +2353,6 @@ customize.colorsMenuOnThemeChange = function() {
*/
customize.colorsMenuPreselectTile = function() {
const themeInfo = assert(ntpApiHandle.themeBackgroundInfo);
-
let tile;
if (themeInfo.usingDefaultTheme) {
tile = $(customize.IDS.COLORS_DEFAULT_ICON);
@@ -2383,6 +2392,7 @@ customize.colorsMenuPreselectTile = function() {
if (!customize.preselectedOptions.colorsMenuTile) {
customize.preselectedOptions.colorsMenuTile = tile;
}
+
customize.updateColorsMenuTileSelection(
/** @type HTMLElement */ (tile));
}
@@ -2393,11 +2403,8 @@ customize.colorsMenuPreselectTile = function() {
* menu.
*/
customize.isColorOptionSelected = function() {
- return (!customize.preselectedOptions.colorsMenuTile &&
- customize.selectedOptions.color) ||
- (customize.preselectedOptions.colorsMenuTile &&
- customize.selectedOptions.color.id !==
- customize.preselectedOptions.colorsMenuTile.id);
+ return customize.preselectedOptions.colorsMenuTile !==
+ customize.selectedOptions.color;
};
/**
@@ -2428,10 +2435,9 @@ customize.cancelColor = function() {
};
/**
- * Reset Colors Menu elements to the default state, specifically the color
- * picker.
+ * Reset color picker to its default state.
*/
-customize.resetColorsMenu = function() {
+customize.resetColorPicker = function() {
customize.customColorPicked = customize.defaultCustomColor;
$(customize.IDS.COLOR_PICKER).value = null;
$(customize.IDS.COLORS_MENU).style.setProperty('--custom-color-border', '');
@@ -2441,6 +2447,15 @@ customize.resetColorsMenu = function() {
};
/**
+ * Reset color selection.
+ */
+customize.resetColorsSelectedOptions = function() {
+ customize.richerPicker_removeSelectedState(customize.selectedOptions.color);
+ customize.selectedOptions.color = null;
+ customize.preselectedOptions.colorsMenuTile = null;
+};
+
+/**
* Converts an RGBA component into hex format.
* @param {number} c RGBA component.
* @return {string} RGBA component in hex format.
diff --git a/chromium/chrome/browser/resources/local_ntp/doodles.css b/chromium/chrome/browser/resources/local_ntp/doodles.css
index 885619db2c1..ca9a379de2d 100644
--- a/chromium/chrome/browser/resources/local_ntp/doodles.css
+++ b/chromium/chrome/browser/resources/local_ntp/doodles.css
@@ -263,7 +263,8 @@ body.alternate-logo #logo-non-white {
#ddlsd-title {
color: #212121;
font-size: 22px;
- padding: 0 40px 16px 0;
+ padding-bottom: 16px;
+ padding-inline-end: 40px;
}
@media (prefers-color-scheme: dark) {
@@ -273,7 +274,6 @@ body.alternate-logo #logo-non-white {
}
#ddlsd-close {
- background: url(icons/close.svg) no-repeat;
height: 24px;
position: absolute;
right: 22px;
@@ -281,6 +281,29 @@ body.alternate-logo #logo-non-white {
width: 24px;
}
+[dir=rtl] #ddlsd-close {
+ left: 22px;
+ right: auto;
+}
+
+#ddlsd-close::before {
+ -webkit-mask-image: url(../../../../ui/webui/resources/images/icon_clear.svg);
+ -webkit-mask-position: center center;
+ -webkit-mask-repeat: no-repeat;
+ -webkit-mask-size: 32px;
+ background-color: #4d4d4d;
+ content: '';
+ display: block;
+ height: 100%;
+ width: 100%;
+}
+
+@media (prefers-color-scheme: dark) {
+ #ddlsd-close::before {
+ background-color: rgb(var(--GG500-rgb));
+ }
+}
+
#ddlsd-fbb {
background: url(icons/facebook.svg) no-repeat center;
}
@@ -315,7 +338,6 @@ body.alternate-logo #logo-non-white {
background: url(icons/copy.svg) no-repeat center;
background-size: contain;
display: inline-block;
- float: right;
height: 36px;
margin: 5px;
width: 36px;
@@ -338,8 +360,8 @@ body.alternate-logo #logo-non-white {
}
#ddlsd-link {
+ display: flex;
margin: 6px;
- overflow: hidden;
}
#ddlsd-text-ctr {
diff --git a/chromium/chrome/browser/resources/local_ntp/externs.js b/chromium/chrome/browser/resources/local_ntp/externs.js
index 04feef1b03c..945e9807564 100644
--- a/chromium/chrome/browser/resources/local_ntp/externs.js
+++ b/chromium/chrome/browser/resources/local_ntp/externs.js
@@ -27,13 +27,13 @@ let MostVisitedData;
* chrome/browser/search/local_ntp_source.cc:
* LocalNtpSource::SearchConfigurationProvider::UpdateConfigData()
* @typedef {{chromeColors: boolean,
- * enableShortcutsGrid: boolean,
* googleBaseUrl: string,
* isAccessibleBrowser: boolean,
* isGooglePage: boolean,
+ * realboxEnabled: boolean,
* richerPicker: boolean,
- * showFakeboxPlaceholderOnFocus: boolean,
- * translatedStrings: Array<string>}}
+ * suggestionTransparencyEnabled: boolean,
+ * translatedStrings: Object<string>}}
*/
let configData;
@@ -108,8 +108,9 @@ let og;
* The type of the middle-slot promo data object. The definition is based on
* chrome/browser/search/local_ntp_source.cc:
* ConvertPromoDataToDict()
- * @typedef {{promoHtml: string,
- * promoLogUrl: string}}
+ * @typedef {{promoHtml: (string|undefined),
+ * promoLogUrl: (string|undefined),
+ * promoId: (string|undefined)}}
*/
let promo;
@@ -373,18 +374,73 @@ window.chrome.embeddedSearch.newTabPage.undoMostVisitedDeletion;
*/
window.chrome.embeddedSearch.newTabPage.updateCustomLink;
+/** @param {string} promoId */
+window.chrome.embeddedSearch.newTabPage.blocklistPromo;
+
/**
* Embedded Search API methods defined in
* chrome/renderer/searchbox/searchbox_extension.cc:
* SearchBoxBindings::GetObjectTemplateBuilder()
*/
window.chrome.embeddedSearch.searchBox;
+/** @param {number} line */
+window.chrome.embeddedSearch.searchBox.deleteAutocompleteMatch;
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;
+/** @param {string} input */
+window.chrome.embeddedSearch.searchBox.queryAutocomplete;
+/** @param {boolean} clearResult */
+window.chrome.embeddedSearch.searchBox.stopAutocomplete;
+
+/** @typedef {{offset: number, style: number}} */
+let ACMatchClassification;
+
+/**
+ * @typedef {{
+ * allowedToBeDefaultMatch: boolean,
+ * contents: string,
+ * contentsClass: !Array<!ACMatchClassification>,
+ * description: string,
+ * descriptionClass: !Array<!ACMatchClassification>,
+ * destinationUrl: string,
+ * inlineAutocompletion: string,
+ * isSearchType: boolean,
+ * fillIntoEdit: string,
+ * supportsDeletion: boolean,
+ * swapContentsAndDescription: boolean,
+ * type: string,
+ * }}
+ */
+let AutocompleteMatch;
+
+/** @enum {number} */
+const AutocompleteResultStatus = {};
+
+/**
+ * @typedef {{
+ * input: string,
+ * matches: !Array<!AutocompleteMatch>,
+ * status: !AutocompleteResultStatus,
+ * }}
+ */
+let AutocompleteResult;
+
+/** @type {function(!AutocompleteResult):void} */
+window.chrome.embeddedSearch.searchBox.onqueryautocompletedone;
+
+/**
+ * @typedef {{
+ * success: boolean,
+ * matches: !Array<!AutocompleteMatch>,
+ * }}
+ */
+let DeleteAutocompleteMatchResult;
+/** @type {function(!DeleteAutocompleteMatchResult):void} */
+window.chrome.embeddedSearch.searchBox.ondeleteautocompletematch;
/**************************** Translated Strings *****************************/
@@ -393,7 +449,6 @@ window.chrome.embeddedSearch.searchBox.stopCapturingKeyStrokes;
* chrome/browser/search/local_ntp_source.cc:
* GetTranslatedStrings()
*/
-
configData.translatedStrings.addLinkTitle;
configData.translatedStrings.addLinkTooltip;
configData.translatedStrings.attributionIntro;
@@ -407,6 +462,7 @@ configData.translatedStrings.copyLink;
configData.translatedStrings.customizeThisPage;
configData.translatedStrings.defaultWallpapers;
configData.translatedStrings.details;
+configData.translatedStrings.dismissPromo;
configData.translatedStrings.editLinkTitle;
configData.translatedStrings.editLinkTooltip;
configData.translatedStrings.fakeboxMicrophoneTooltip;
@@ -432,6 +488,8 @@ configData.translatedStrings.noVoice;
configData.translatedStrings.otherError;
configData.translatedStrings.permissionError;
configData.translatedStrings.ready;
+configData.translatedStrings.realboxSeparator;
+configData.translatedStrings.removeSuggestion;
configData.translatedStrings.removeThumbnailTooltip;
configData.translatedStrings.restoreDefaultBackground;
configData.translatedStrings.restoreDefaultLinks;
diff --git a/chromium/chrome/browser/resources/local_ntp/icons/clock.svg b/chromium/chrome/browser/resources/local_ntp/icons/clock.svg
new file mode 100644
index 00000000000..d4420ae7d7a
--- /dev/null
+++ b/chromium/chrome/browser/resources/local_ntp/icons/clock.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><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 8z"/><path d="M0 0h24v24H0z" fill="none"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/local_ntp/icons/close.svg b/chromium/chrome/browser/resources/local_ntp/icons/close.svg
deleted file mode 100644
index 282fa77de8f..00000000000
--- a/chromium/chrome/browser/resources/local_ntp/icons/close.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><defs><style>.a{fill:none;stroke:#4d4d4d;stroke-miterlimit:10;stroke-width:3px}</style></defs><path class="a" d="M3.5 3.5L21 21M3.5 21L21 3.5"/></svg> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/local_ntp/icons/dont_show.png b/chromium/chrome/browser/resources/local_ntp/icons/dont_show.png
new file mode 100644
index 00000000000..bcf13913d64
--- /dev/null
+++ b/chromium/chrome/browser/resources/local_ntp/icons/dont_show.png
Binary files differ
diff --git a/chromium/chrome/browser/resources/local_ntp/icons/dont_show_2x.png b/chromium/chrome/browser/resources/local_ntp/icons/dont_show_2x.png
new file mode 100644
index 00000000000..815d7e7a84a
--- /dev/null
+++ b/chromium/chrome/browser/resources/local_ntp/icons/dont_show_2x.png
Binary files differ
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.css b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
index 206b5f9e96f..0a02e7356be 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.css
@@ -93,7 +93,9 @@ button {
}
#logo,
-#fakebox-container {
+#fakebox-container,
+#realbox-container {
+ --searchbox-height: 44px;
flex-shrink: 0;
}
@@ -122,67 +124,225 @@ body.hide-fakebox #fakebox {
width: var(--content-width);
}
-#fakebox {
+#realbox-input-wrapper {
+ position: relative;
+ z-index: 0;
+}
+
+#fakebox,
+#realbox {
background: white;
border-radius: 22px;
- box-shadow: 0 1px 6px 0 rgba(32, 33, 36, .28);
box-sizing: border-box;
- cursor: text;
font-size: 16px;
- height: 44px;
- margin: 0 auto;
- max-width: 584px;
+ height: var(--searchbox-height);
opacity: 1;
position: relative;
transition: none;
}
+#fakebox,
+#realbox-input-wrapper:not(.show-matches) #realbox,
+#realbox-input-wrapper.show-matches #realbox-matches {
+ box-shadow: 0 1px 6px 0 rgba(32, 33, 36, .28);
+}
+
+#fakebox,
+#realbox-input-wrapper {
+ margin: 0 auto;
+ max-width: 584px;
+}
+
+#fakebox {
+ cursor: text;
+}
+
+#realbox {
+ border: none;
+ display: block;
+ outline: none;
+ padding-inline-end: 48px;
+ width: 100%;
+ z-index: 2;
+}
+
+#realbox::-webkit-search-decoration,
+#realbox::-webkit-search-cancel-button,
+#realbox::-webkit-search-results-button,
+#realbox::-webkit-search-results-decoration {
+ display: none;
+}
+
+#realbox::placeholder {
+ color: rgb(117, 117, 117);
+}
+
+#realbox:focus::placeholder {
+ color: transparent;
+}
+
@media (prefers-color-scheme: dark) {
- #fakebox {
+ #fakebox,
+ #realbox-input-wrapper:not(.show-matches) #realbox,
+ #realbox-input-wrapper.show-matches #realbox-matches {
box-shadow: 0 1px 6px 0 rgba(32, 33, 36, .78);
}
}
-.non-google-page #fakebox-container {
+.non-google-page :-webkit-any(#fakebox-container, #realbox-container) {
display: none;
}
-#fakebox > input {
- bottom: 0;
- box-sizing: border-box;
+#realbox-matches {
+ background: white;
+ border-radius: 8px;
+ display: none;
left: 0;
- margin: 0;
- opacity: 0;
- padding-inline-start: 20px;
+ overflow: hidden;
+ padding-top: var(--searchbox-height);
position: absolute;
+ right: 0;
top: 0;
- width: 100%;
+ z-index: 1;
}
-html[dir=rtl] #fakebox > input {
- right: 0;
+#realbox-input-wrapper.show-matches #realbox-matches {
+ display: flex;
+ flex-direction: column;
+}
+
+#realbox-matches :-webkit-any(a, span) {
+ color: inherit;
+ font-family: inherit;
+}
+
+#realbox-matches a {
+ background-position: 16px center;
+ background-repeat: no-repeat;
+ background-size: 24px;
+ font-size: 16px;
+ outline: none;
+ overflow: hidden;
+ padding-bottom: 8px;
+ padding-inline-end: 16px;
+ padding-inline-start: 48px;
+ padding-top: 8px;
+ position: relative;
+ text-decoration: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+[dir=rtl] #realbox-matches a {
+ background-position-x: calc(100% - 16px);
+}
+
+#realbox-matches.removable a {
+ padding-inline-end: 48px;
+}
+
+.clock-icon,
+.search-icon {
+ -webkit-mask-position: center;
+ -webkit-mask-repeat: no-repeat;
+ background-color: rgb(117, 117, 117);
+ bottom: 0;
+ left: 16px;
+ position: absolute;
+ top: 0;
+ width: 24px;
+}
+
+.clock-icon {
+ -webkit-mask-image: url(icons/clock.svg);
+ -webkit-mask-size: 16px;
}
-#fakebox-search-icon {
+.search-icon {
-webkit-mask-image:
url(../../../../ui/webui/resources/images/icon_search.svg);
+ -webkit-mask-size: 20px;
+}
+
+html[dir=rtl] :-webkit-any(.clock-icon, .search-icon) {
+ right: 16px;
+}
+
+#realbox-matches a:-webkit-any(:hover, .selected) {
+ background-color: rgb(var(--GG100-rgb));
+}
+
+#realbox-matches a:focus-within {
+ background-color: rgb(var(--GG200-rgb));
+}
+
+#realbox-matches .match {
+ font-weight: bold;
+}
+
+#realbox-matches .dim {
+ color: rgb(var(--GG600-rgb));
+}
+
+#realbox-matches .url {
+ color: rgb(var(--GB600-rgb));
+}
+
+#realbox-matches .remove-match {
+ border-radius: 50%;
+ height: 24px;
+ position: absolute;
+ right: 16px;
+ top: 4px;
+ width: 24px;
+}
+
+[dir=rtl] #realbox-matches .remove-match {
+ left: 16px;
+ right: auto;
+}
+
+#realbox-matches .remove-match:hover {
+ background-color: rgba(var(--GG900-rgb), .08);
+}
+
+#realbox-matches .remove-match:focus-within {
+ background-color: rgba(var(--GG900-rgb), .16);
+}
+
+#realbox-matches .remove-icon {
+ height: 100%;
+ width: 100%;
+}
+
+#realbox-matches a:-webkit-any(:hover, :focus-within) .remove-icon {
+ -webkit-mask-image: url(../../../../ui/webui/resources/images/icon_clear.svg);
+ -webkit-mask-position: center;
-webkit-mask-repeat: no-repeat;
- -webkit-mask-size: 100%;
- background: 24px 24px rgb(117, 117, 117);
+ -webkit-mask-size: 16px;
+ background-color: rgb(var(--GG900-rgb));
+}
+
+#fakebox > input {
bottom: 0;
- height: 24px;
+ box-sizing: border-box;
left: 0;
- margin: auto 0;
- margin-inline-start: 16px;
+ margin: 0;
+ opacity: 0;
+ padding-inline-start: 20px;
position: absolute;
top: 0;
- width: 24px;
+ width: 100%;
}
-html[dir=rtl] #fakebox-search-icon {
+html[dir=rtl] #fakebox > input {
right: 0;
}
+#fakebox .search-icon {
+ -webkit-mask-size: 20px;
+}
+
#fakebox-text {
bottom: 0;
color: rgb(117, 117, 117);
@@ -192,7 +352,6 @@ html[dir=rtl] #fakebox-search-icon {
line-height: 44px;
margin: auto 0;
overflow: hidden;
- padding-inline-start: 48px;
position: absolute;
right: 44px;
text-align: initial;
@@ -209,6 +368,11 @@ html[dir=rtl] #fakebox-text {
right: 0;
}
+#fakebox-text,
+#realbox {
+ padding-inline-start: 48px;
+}
+
#fakebox-cursor {
background: #333;
/* Total 16px height: (46px fakebox height - 2px border) - 14px top - 14px
@@ -226,7 +390,7 @@ html[dir=rtl] #fakebox-cursor {
right: 48px;
}
-#fakebox-microphone {
+.microphone-icon {
background: url(icons/googlemic_clr_24px.svg) no-repeat center;
background-size: 21px 21px;
bottom: 0;
@@ -239,11 +403,15 @@ html[dir=rtl] #fakebox-cursor {
width: 21px;
}
-html[dir=rtl] #fakebox-microphone {
+html[dir=rtl] .microphone-icon {
left: 0;
right: auto;
}
+#realbox-input-wrapper :-webkit-any(.search-icon, .microphone-icon) {
+ z-index: 3;
+}
+
@keyframes blink {
0% {
opacity: 1;
@@ -253,8 +421,8 @@ html[dir=rtl] #fakebox-microphone {
}
}
-body.fakebox-drag-focused #fakebox-text:not(.show-placeholder),
-body.fakebox-focused #fakebox-text:not(.show-placeholder) {
+body.fakebox-drag-focused #fakebox-text,
+body.fakebox-focused #fakebox-text {
visibility: hidden;
}
@@ -339,7 +507,7 @@ body.fakebox-focused #fakebox-cursor {
}
@media (prefers-color-scheme: dark) {
- body:not(.light-chip) #mv-notice {
+ body:not(.light-chip) #mv-notice {
background-color: rgb(var(--GG900-rgb));
border-color: rgba(0, 0, 0, .1);
}
@@ -356,7 +524,7 @@ body.fakebox-focused #fakebox-cursor {
}
@media (prefers-color-scheme: dark) {
- body:not(.light-chip) #mv-notice span {
+ body:not(.light-chip) #mv-notice span {
color: rgb(var(--GG200-rgb));
}
}
@@ -374,7 +542,7 @@ body.fakebox-focused #fakebox-cursor {
}
@media (prefers-color-scheme: dark) {
- body:not(.light-chip) #mv-notice-links span {
+ body:not(.light-chip) #mv-notice-links span {
color: rgb(var(--GB400-dark-rgb));
}
}
@@ -391,7 +559,7 @@ body.fakebox-focused #fakebox-cursor {
}
@media (prefers-color-scheme: dark) {
- body:not(.light-chip) #mv-notice-links
+ body:not(.light-chip) #mv-notice-links
:-webkit-any(span:hover, span:active) {
background-color: rgba(var(--GB400-dark-rgb), .1);
}
@@ -403,8 +571,7 @@ body.fakebox-focused #fakebox-cursor {
}
@media (prefers-color-scheme: dark) {
- body:not(.light-chip) .default-theme.dark #mv-msg,
- body:not(.light-chip) .default-theme.dark #mv-notice-links span {
+ body:not(.light-chip) #mv-msg {
color: rgb(var(--GG200-rgb));
}
}
@@ -596,13 +763,13 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
#promo {
bottom: 16px;
- display: none;
left: 0;
pointer-events: none;
position: fixed;
right: 0;
text-align: center;
transition: bottom 400ms;
+ visibility: hidden;
}
#promo.float-down {
@@ -610,6 +777,7 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
}
#promo > div {
+ --dismiss-background-rgb: var(--GG900-rgb);
background-color: #FFF;
border: 1px solid rgb(var(--GG300-rgb));
border-radius: 16px;
@@ -617,34 +785,69 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
color: rgb(var(--GG700-rgb));
display: inline-block;
font-size: 12px;
- line-height: 32px;
+ height: 32px;
+ line-height: 30px; /* Height - 1px border-top - 1px border-bottom. */
margin-bottom: 0;
- max-width: 505px;
+ /* TODO(crbug.com/969062): this magic constant would be better implemented as
+ * real multi-line promo text support or a better QA process to check that
+ * promo messages aren't ellided. It's ultimately quite hard to make any pixel
+ * value here useful as font face, sizes, and zoom can all vary. Pushing for
+ * a more dynamic UI or better qualification process has been met with
+ * significant resistance, so we keep arbitrarily changing this value. */
+ max-width: 537px;
overflow: hidden;
padding: 0 16px;
pointer-events: all;
+ position: relative;
text-overflow: ellipsis;
white-space: nowrap;
}
+#promo.dismissable > div {
+ padding-inline-end: 36px; /* +24px for dismiss-icon - 4px less end padding */
+}
+
@media (prefers-color-scheme: dark) {
body:not(.light-chip) #promo > div {
+ --dismiss-background-rgb: var(--GG100-rgb);
background-color: rgb(var(--GG900-rgb));
border-color: rgba(0, 0, 0, .1);
color: rgb(var(--GG200-rgb));
}
}
-/**
- * Hide the promo if the window is too small:
- * max-width = promo.max-width (505px) + 2 * edit gear icon (16px + 28px + 8px)
- * max-height = ntp-contents.max-height (628px) + promo div height (16px + 22px)
- */
-@media only screen and (max-width: 609px),
- screen and (max-height: 666px) {
- #promo > div {
- display: none;
- }
+#promo > div .dismiss-promo {
+ border-radius: 50%;
+ height: 24px;
+ position: absolute;
+ right: 4px;
+ top: 3px; /* 4px from top - 1px of border. */
+ width: 24px;
+}
+
+[dir=rtl] #promo > div .dismiss-promo {
+ left: 4px;
+ right: auto;
+}
+
+#promo > div .dismiss-icon {
+ -webkit-mask-image: url(../../../../ui/webui/resources/images/icon_clear.svg);
+ -webkit-mask-position: center center;
+ -webkit-mask-repeat: no-repeat;
+ -webkit-mask-size: 16px;
+ background-color: rgb(var(--dismiss-background-rgb));
+ display: block;
+ height: 100%;
+ outline: none;
+ width: 100%;
+}
+
+#promo > div .dismiss-promo:hover {
+ background-color: rgba(var(--dismiss-background-rgb), .08);
+}
+
+#promo > div .dismiss-promo:focus-within {
+ background-color: rgba(var(--dismiss-background-rgb), .16);
}
#promo > div > a {
@@ -665,7 +868,9 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
#promo > div > img {
border-radius: 50%;
height: 24px;
- margin: 0 8px 2px -12px;
+ margin-bottom: 2px;
+ margin-inline-end: 8px;
+ margin-inline-start: -12px;
object-fit: cover;
vertical-align: middle;
width: 24px;
@@ -677,8 +882,7 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
}
}
-#one-google.show-element,
-#promo.show-element {
+#one-google.show-element {
display: block;
}
@@ -733,7 +937,6 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
font-size: 14px;
height: 32px;
left: 0;
- line-height: 32px;
margin-bottom: 16px;
outline: none;
text-align: start;
@@ -891,7 +1094,6 @@ html[dir=rtl] .menu-option {
margin-inline-start: 40px;
position: relative;
width: 568px;
- z-index: 1;
}
.menu-panel {
@@ -951,6 +1153,7 @@ html[dir=rtl] .menu-option {
}
}
+#customization-menu.using-mouse-nav,
.using-mouse-nav .bg-sel-tile:focus {
outline: none;
}
@@ -1656,6 +1859,7 @@ html[dir=rtl] #colors-menu .bg-sel-tile .selected-check {
border: 1px solid rgb(var(--GG200-rgb));
border-radius: 4px;
display: none;
+ font-size: 13px;
height: 64px;
margin-bottom: 24px;
max-width: 544px;
@@ -1670,7 +1874,6 @@ html[dir=rtl] #colors-menu .bg-sel-tile .selected-check {
#colors-theme.visible {
display: flex;
- font-size: small;
}
#colors-theme > * {
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.html b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
index 0893eb63f94..8c7f4b11a7c 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.html
@@ -1,5 +1,5 @@
<!doctype html>
-<html lang="$i18n{language}"><!-- TODO(dbeam): dir="$i18n{textdirection}"? -->
+<html lang="$i18n{language}" dir="$i18n{textdirection}">
<!-- 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. -->
@@ -65,14 +65,24 @@
</div>
</div>
- <div id="fakebox-container">
+ <div id="fakebox-container" $i18n{hiddenIfRealboxEnabled}>
<div id="fakebox">
- <div id="fakebox-search-icon"></div>
+ <div class="search-icon"></div>
<div id="fakebox-text"></div>
<input id="fakebox-input" autocomplete="off" tabindex="-1" type="url"
aria-hidden="true">
<div id="fakebox-cursor"></div>
- <button id="fakebox-microphone" hidden></button>
+ <button id="fakebox-microphone" class="microphone-icon" hidden></button>
+ </div>
+ </div>
+
+ <div id="realbox-container" $i18n{hiddenIfRealboxDisabled}>
+ <div id="realbox-input-wrapper">
+ <div class="search-icon"></div>
+ <input id="realbox" type="search" autocomplete="off" spellcheck="false"
+ aria-live="polite" autofocus>
+ <button id="realbox-microphone" class="microphone-icon" hidden></button>
+ <div id="realbox-matches"></div>
</div>
</div>
@@ -111,7 +121,7 @@
<span id="edit-bg-text">$i18n{customizeButton}</span>
</div>
- <a id="custom-bg-attr"></a>
+ <div id="custom-bg-attr"></div>
</div>
<dialog div id="edit-bg-dialog">
@@ -147,10 +157,10 @@
<button id="ddlsd-emb" class="ddlsd-sbtn"></button>
<hr id="ddlsd-hr">
<div id="ddlsd-link">
- <button id="ddlsd-copy"></button>
<span id="ddlsd-text-ctr">
<input type="text" id="ddlsd-text" dir="ltr">
</span>
+ <button id="ddlsd-copy"></button>
</div>
</div>
</dialog>
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp.js b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
index 21ebc4ef20f..50972ac06fb 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp.js
@@ -31,6 +31,37 @@ let tilesAreLoaded = false;
function LocalNTP() {
'use strict';
+// Type definitions.
+
+/** @enum {number} */
+const ACMatchClassificationStyle = {
+ NONE: 0,
+ URL: 1 << 0,
+ MATCH: 1 << 1,
+ DIM: 1 << 2,
+};
+
+/** @enum {number} */
+const AutocompleteResultStatus = {
+ SUCCESS: 0,
+ SKIPPED: 1,
+};
+
+/** @type {string} */
+let lastInput;
+
+/** @typedef {{inline: string, text: string}} */
+let RealboxOutput;
+
+/**
+ * @typedef {{
+ * moveCursorToEnd: (boolean|undefined),
+ * inline: (string|undefined),
+ * text: (string|undefined),
+ * }}
+ */
+let RealboxOutputUpdate;
+
// Constants.
/**
@@ -40,16 +71,17 @@ function LocalNTP() {
*/
const CLASSES = {
ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
+ // Shows a clock next to historical realbox results.
+ CLOCK_ICON: 'clock-icon',
// Applies styles to dialogs used in customization.
CUSTOMIZE_DIALOG: 'customize-dialog',
- DARK: 'dark',
- DEFAULT_THEME: 'default-theme',
DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
+ DISMISSABLE: 'dismissable',
+ DISMISS_ICON: 'dismiss-icon',
+ DISMISS_PROMO: 'dismiss-promo',
// Extended and elevated style for customization entry point.
ENTRY_POINT_ENHANCED: 'ep-enhanced',
FAKEBOX_FOCUS: 'fakebox-focused', // Applies focus styles to the fakebox
- // Applied when the fakebox placeholder text should not be hidden on focus.
- SHOW_PLACEHOLDER: 'show-placeholder',
// Applies float animations to the Most Visited notification
FLOAT_DOWN: 'float-down',
FLOAT_UP: 'float-up',
@@ -63,20 +95,22 @@ const CLASSES = {
LEFT_ALIGN_ATTRIBUTION: 'left-align-attribution',
// Vertically centers the most visited section for a non-Google provided page.
NON_GOOGLE_PAGE: 'non-google-page',
- NON_WHITE_BG: 'non-white-bg',
- RTL: 'rtl', // Right-to-left language text.
+ REMOVABLE: 'removable',
+ REMOVE_ICON: 'remove-icon',
+ REMOVE_MATCH: 'remove-match',
+ SEARCH_ICON: 'search-icon', // Magnifying glass/search icon.
+ SELECTED: 'selected', // A selected (via up/down arrow key) realbox match.
SHOW_ELEMENT: 'show-element',
+ // When the realbox has matches to show.
+ SHOW_MATCHES: 'show-matches',
// Applied when the doodle notifier should be shown instead of the doodle.
USE_NOTIFIER: 'use-notifier',
};
-/**
- * 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)';
+const SEARCH_HISTORY_MATCH_TYPES = [
+ 'search-history',
+ 'search-suggest-personalized',
+];
/**
* The period of time (ms) before transitions can be applied to a toast
@@ -101,7 +135,6 @@ const IDS = {
ERROR_NOTIFICATION_LINK: 'error-notice-link',
ERROR_NOTIFICATION_MSG: 'error-notice-msg',
FAKEBOX: 'fakebox',
- FAKEBOX_ICON: 'fakebox-search-icon',
FAKEBOX_INPUT: 'fakebox-input',
FAKEBOX_TEXT: 'fakebox-text',
FAKEBOX_MICROPHONE: 'fakebox-microphone',
@@ -112,6 +145,10 @@ const IDS = {
NTP_CONTENTS: 'ntp-contents',
OGB: 'one-google',
PROMO: 'promo',
+ REALBOX: 'realbox',
+ REALBOX_INPUT_WRAPPER: 'realbox-input-wrapper',
+ REALBOX_MATCHES: 'realbox-matches',
+ REALBOX_MICROPHONE: 'realbox-microphone',
RESTORE_ALL_LINK: 'mv-restore',
SUGGESTIONS: 'suggestions',
TILES: 'mv-tiles',
@@ -188,7 +225,7 @@ const NOTIFICATION_TIMEOUT = 10000;
*/
const NTP_DESIGN = {
backgroundColor: [255, 255, 255, 255],
- darkBackgroundColor: [50, 54, 57, 255],
+ darkBackgroundColor: [53, 54, 58, 255],
iconBackgroundColor: [241, 243, 244, 255], /** GG100 */
iconDarkBackgroundColor: [32, 33, 36, 255], /** GG900 */
numTitleLines: 1,
@@ -196,16 +233,21 @@ const NTP_DESIGN = {
titleColorAgainstDark: [248, 249, 250, 255], /** GG050 */
};
-/**
- * Background colors considered "white". Used to determine if it is possible to
- * display a Google Doodle, or if the notifier should be used instead. Also used
- * to determine if a colored or white logo should be used.
- * @const
- */
-const WHITE_BACKGROUND_COLORS = ['rgba(255,255,255,1)', 'rgba(0,0,0,0)'];
+const REALBOX_KEYDOWN_HANDLED_KEYS = [
+ 'ArrowDown',
+ 'ArrowUp',
+ 'Delete',
+ 'Enter',
+ 'Escape',
+ 'PageDown',
+ 'PageUp',
+];
// Local statics.
+/** @type {!Array<!AutocompleteMatch>} */
+let autocompleteMatches = [];
+
/**
* The currently visible notification element. Null if no notification is
* present.
@@ -226,6 +268,16 @@ let delayedHideNotification = null;
*/
let isDarkModeEnabled = false;
+/** Used to prevent inline autocompleting recently deleted output. */
+let isDeletingInput = false;
+
+/**
+ * The rendered autocomplete match currently being deleted, or null if there
+ * isn't one.
+ * @type {?Element}
+ */
+let matchElBeingDeleted = null;
+
/**
* The last blacklisted tile rid if any, which by definition should not be
* filler.
@@ -234,6 +286,13 @@ let isDarkModeEnabled = false;
let lastBlacklistedTile = null;
/**
+ * Last text/inline autocompletion shown in the realbox (either by user input or
+ * outputting autocomplete matches).
+ * @type {!RealboxOutput}
+ */
+let lastOutput = {text: '', inline: ''};
+
+/**
* The browser embeddedSearch.newTabPage object.
* @type {Object}
*/
@@ -241,6 +300,29 @@ let ntpApiHandle;
// Helper methods.
+/** @return {boolean} */
+function areRealboxMatchesVisible() {
+ return $(IDS.REALBOX_INPUT_WRAPPER).classList.contains(CLASSES.SHOW_MATCHES);
+}
+
+/**
+ * @param {number} style
+ * @return {!Array<string>}
+ */
+function classificationStyleToClasses(style) {
+ const classes = [];
+ if (style & ACMatchClassificationStyle.DIM) {
+ classes.push('dim');
+ }
+ if (style & ACMatchClassificationStyle.MATCH) {
+ classes.push('match');
+ }
+ if (style & ACMatchClassificationStyle.URL) {
+ classes.push('url');
+ }
+ return classes;
+}
+
/**
* Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
* @param {Array<number>} color Array of rgba color components.
@@ -296,9 +378,6 @@ function createIframes() {
if (configData.isGooglePage) {
args.push('enableCustomLinks=1');
- if (configData.enableShortcutsGrid) {
- args.push('enableGrid=1');
- }
args.push(
'addLink=' +
encodeURIComponent(configData.translatedStrings.addLinkTitle));
@@ -536,6 +615,12 @@ function getThemeBackgroundInfo() {
// backgroundImage is in the form: url("actual url"). Remove everything
// except the actual url.
info.imageUrl = preview.style.backgroundImage.slice(5, -2);
+
+ if (preview.dataset.hasImage === 'true') {
+ info.attribution1 = preview.dataset.attributionLine1;
+ info.attribution2 = preview.dataset.attributionLine2;
+ info.attributionActionUrl = preview.dataset.attributionActionUrl;
+ }
}
return info;
}
@@ -569,7 +654,7 @@ function handlePostMessage(event) {
$(IDS.SUGGESTIONS).style.visibility = 'visible';
}
if ($(IDS.PROMO)) {
- $(IDS.PROMO).classList.add(CLASSES.SHOW_ELEMENT);
+ showPromoIfNotOverlappingAndTrackResizes();
}
if (customLinksEnabled()) {
$(customize.IDS.CUSTOM_LINKS_RESTORE_DEFAULT)
@@ -672,70 +757,89 @@ function init() {
customize.init(showErrorNotification, hideNotification);
- if (configData.showFakeboxPlaceholderOnFocus) {
- $(IDS.FAKEBOX_TEXT).classList.add(CLASSES.SHOW_PLACEHOLDER);
- }
+ if (configData.realboxEnabled) {
+ const realboxEl = $(IDS.REALBOX);
+ realboxEl.placeholder = configData.translatedStrings.searchboxPlaceholder;
+ realboxEl.addEventListener('copy', onRealboxCutCopy);
+ realboxEl.addEventListener('cut', onRealboxCutCopy);
+ realboxEl.addEventListener('input', onRealboxInput);
- // Set up the fakebox (which only exists on the Google NTP).
- ntpApiHandle.oninputstart = onInputStart;
- ntpApiHandle.oninputcancel = onInputCancel;
+ const realboxWrapper = $(IDS.REALBOX_INPUT_WRAPPER);
+ realboxWrapper.addEventListener('focusin', onRealboxWrapperFocusIn);
+ realboxWrapper.addEventListener('focusout', onRealboxWrapperFocusOut);
- if (ntpApiHandle.isInputInProgress) {
- onInputStart();
- }
+ searchboxApiHandle.onqueryautocompletedone = onQueryAutocompleteDone;
+ searchboxApiHandle.ondeleteautocompletematch = onDeleteAutocompleteMatch;
- $(IDS.FAKEBOX_TEXT).textContent =
- configData.translatedStrings.searchboxPlaceholder;
+ if (!iframesAndVoiceSearchDisabledForTesting) {
+ speech.init(
+ configData.googleBaseUrl, configData.translatedStrings,
+ $(IDS.REALBOX_MICROPHONE), searchboxApiHandle);
+ }
- if (!iframesAndVoiceSearchDisabledForTesting) {
- speech.init(
- configData.googleBaseUrl, configData.translatedStrings,
- $(IDS.FAKEBOX_MICROPHONE), searchboxApiHandle);
- }
+ utils.disableOutlineOnMouseClick($(IDS.REALBOX_MICROPHONE));
+ } else {
+ // Set up the fakebox (which only exists on the Google NTP).
+ ntpApiHandle.oninputstart = onInputStart;
+ ntpApiHandle.oninputcancel = onInputCancel;
- // Listener for updating the key capture state.
- document.body.onmousedown = function(event) {
- if (isFakeboxClick(event)) {
- searchboxApiHandle.startCapturingKeyStrokes();
- } else if (isFakeboxFocused()) {
- searchboxApiHandle.stopCapturingKeyStrokes();
+ if (ntpApiHandle.isInputInProgress) {
+ onInputStart();
}
- };
- searchboxApiHandle.onkeycapturechange = function() {
- setFakeboxFocus(searchboxApiHandle.isKeyCaptureEnabled);
- };
- const inputbox = $(IDS.FAKEBOX_INPUT);
- inputbox.onpaste = function(event) {
- event.preventDefault();
- // Send pasted text to Omnibox.
- const text = event.clipboardData.getData('text/plain');
- if (text) {
- searchboxApiHandle.paste(text);
+
+ $(IDS.FAKEBOX_TEXT).textContent =
+ configData.translatedStrings.searchboxPlaceholder;
+
+ if (!iframesAndVoiceSearchDisabledForTesting) {
+ speech.init(
+ configData.googleBaseUrl, configData.translatedStrings,
+ $(IDS.FAKEBOX_MICROPHONE), searchboxApiHandle);
}
- };
- inputbox.ondrop = function(event) {
- event.preventDefault();
- const text = event.dataTransfer.getData('text/plain');
- if (text) {
- searchboxApiHandle.paste(text);
+
+ // Listener for updating the key capture state.
+ document.body.onmousedown = function(event) {
+ if (isFakeboxClick(event)) {
+ searchboxApiHandle.startCapturingKeyStrokes();
+ } else if (isFakeboxFocused()) {
+ searchboxApiHandle.stopCapturingKeyStrokes();
+ }
+ };
+ searchboxApiHandle.onkeycapturechange = function() {
+ setFakeboxFocus(searchboxApiHandle.isKeyCaptureEnabled);
+ };
+ const inputbox = $(IDS.FAKEBOX_INPUT);
+ inputbox.onpaste = function(event) {
+ event.preventDefault();
+ // Send pasted text to Omnibox.
+ const text = event.clipboardData.getData('text/plain');
+ if (text) {
+ searchboxApiHandle.paste(text);
+ }
+ };
+ inputbox.ondrop = function(event) {
+ event.preventDefault();
+ const text = event.dataTransfer.getData('text/plain');
+ if (text) {
+ searchboxApiHandle.paste(text);
+ }
+ setFakeboxDragFocus(false);
+ };
+ inputbox.ondragenter = function() {
+ setFakeboxDragFocus(true);
+ };
+ inputbox.ondragleave = function() {
+ setFakeboxDragFocus(false);
+ };
+ utils.disableOutlineOnMouseClick($(IDS.FAKEBOX_MICROPHONE));
+
+ // Update the fakebox style to match the current key capturing state.
+ setFakeboxFocus(searchboxApiHandle.isKeyCaptureEnabled);
+ // Also tell the browser that we're capturing, otherwise it's possible
+ // that both fakebox and Omnibox have visible focus at the same time, see
+ // crbug.com/792850.
+ if (searchboxApiHandle.isKeyCaptureEnabled) {
+ searchboxApiHandle.startCapturingKeyStrokes();
}
- setFakeboxDragFocus(false);
- };
- inputbox.ondragenter = function() {
- setFakeboxDragFocus(true);
- };
- inputbox.ondragleave = function() {
- setFakeboxDragFocus(false);
- };
- utils.disableOutlineOnMouseClick($(IDS.FAKEBOX_MICROPHONE));
-
- // Update the fakebox style to match the current key capturing state.
- setFakeboxFocus(searchboxApiHandle.isKeyCaptureEnabled);
- // Also tell the browser that we're capturing, otherwise it's possible
- // that both fakebox and Omnibox have visible focus at the same time, see
- // crbug.com/792850.
- if (searchboxApiHandle.isKeyCaptureEnabled) {
- searchboxApiHandle.startCapturingKeyStrokes();
}
doodles.init();
@@ -745,13 +849,6 @@ function init() {
if (searchboxApiHandle.rtl) {
$(IDS.NOTIFICATION).dir = 'rtl';
- // Grabbing the root HTML element. TODO(dbeam): could this just be <html ...
- // dir="$i18n{textdirection}"> in the .html file instead? It could result in
- // less flicker for RTL users (as HTML/CSS can render before JavaScript has
- // the chance to run).
- document.documentElement.setAttribute('dir', 'rtl');
- // Add class for setting alignments based on language directionality.
- document.documentElement.classList.add(CLASSES.RTL);
}
if (!iframesAndVoiceSearchDisabledForTesting) {
@@ -807,7 +904,10 @@ function injectOneGoogleBar(ogb) {
* doesn't block the main page load.
*/
function injectPromo(promo) {
- if (promo.promoHtml == '') {
+ if (!promo.promoHtml) {
+ if ($(IDS.PROMO)) {
+ $(IDS.PROMO).remove();
+ }
return;
}
@@ -822,16 +922,35 @@ function injectPromo(promo) {
ntpApiHandle.logEvent(LOG_TYPE.NTP_MIDDLE_SLOT_PROMO_SHOWN);
- const links = promoContainer.getElementsByTagName('a');
- if (links[0]) {
- links[0].onclick = function() {
+ const link = promoContainer.querySelector('a');
+ if (link) {
+ link.onclick = function() {
ntpApiHandle.logEvent(LOG_TYPE.NTP_MIDDLE_SLOT_PROMO_LINK_CLICKED);
};
}
+ if (promo.promoId) {
+ const icon = document.createElement('button');
+ icon.classList.add(CLASSES.DISMISS_ICON);
+
+ icon.title = configData.translatedStrings.dismissPromo;
+ icon.onclick = e => {
+ ntpApiHandle.blocklistPromo(promo.promoId);
+ promoContainer.remove();
+ window.removeEventListener('resize', showPromoIfNotOverlapping);
+ };
+
+ const dismiss = document.createElement('div');
+ dismiss.classList.add(CLASSES.DISMISS_PROMO);
+ dismiss.appendChild(icon);
+
+ promoContainer.querySelector('div').appendChild(dismiss);
+ promoContainer.classList.add(CLASSES.DISMISSABLE);
+ }
+
// The the MV tiles are already loaded show the promo immediately.
if (tilesAreLoaded) {
- promoContainer.classList.add(CLASSES.SHOW_ELEMENT);
+ showPromoIfNotOverlappingAndTrackResizes();
}
}
@@ -873,6 +992,71 @@ function isFakeboxFocused() {
document.body.classList.contains(CLASSES.FAKEBOX_DRAG_FOCUS);
}
+/** @return {boolean} */
+function isPromoOverlapping() {
+ const MARGIN = 10;
+
+ /**
+ * @param {string} id
+ * @return {DOMRect}
+ */
+ const rect = id => $(id).getBoundingClientRect();
+
+ const promoRect = $(IDS.PROMO).querySelector('div').getBoundingClientRect();
+
+ if (promoRect.top - MARGIN <= rect(IDS.USER_CONTENT).bottom) {
+ return true;
+ }
+
+ if (window.chrome.embeddedSearch.searchBox.rtl) {
+ const attributionRect = rect(IDS.ATTRIBUTION);
+ if (attributionRect.width > 0 &&
+ promoRect.left - MARGIN <= attributionRect.right) {
+ return true;
+ }
+
+ const editBgRect = rect(customize.IDS.EDIT_BG);
+ assert(editBgRect.width > 0);
+ if (promoRect.left - 2 * MARGIN <= editBgRect.right) {
+ return true;
+ }
+
+ const customAttributionsRect = rect(customize.IDS.ATTRIBUTIONS);
+ if (customAttributionsRect.width > 0 &&
+ promoRect.right + MARGIN >= customAttributionsRect.left) {
+ return true;
+ }
+ } else {
+ const customAttributionsRect = rect(customize.IDS.ATTRIBUTIONS);
+ if (customAttributionsRect.width > 0 &&
+ promoRect.left - MARGIN <= customAttributionsRect.right) {
+ return true;
+ }
+
+ const editBgRect = rect(customize.IDS.EDIT_BG);
+ assert(editBgRect.width > 0);
+ if (promoRect.right + 2 * MARGIN >= editBgRect.left) {
+ return true;
+ }
+
+ const attributionEl = $(IDS.ATTRIBUTION);
+ const attributionRect = attributionEl.getBoundingClientRect();
+ if (attributionRect.width > 0) {
+ const attributionOnLeft =
+ attributionEl.classList.contains(CLASSES.LEFT_ALIGN_ATTRIBUTION);
+ if (attributionOnLeft) {
+ if (promoRect.left - MARGIN <= attributionRect.right) {
+ return true;
+ }
+ } else if (promoRect.right + MARGIN >= attributionRect.left) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
/** Binds event listeners. */
function listen() {
document.addEventListener('DOMContentLoaded', init);
@@ -893,6 +1077,47 @@ function onAddCustomLinkDone(success) {
ntpApiHandle.logEvent(LOG_TYPE.NTP_CUSTOMIZE_SHORTCUT_DONE);
}
+/** @param {!DeleteAutocompleteMatchResult} result */
+function onDeleteAutocompleteMatch(result) {
+ assert(matchElBeingDeleted);
+
+ if (!result.success) {
+ matchElBeingDeleted = null;
+ return;
+ }
+
+ $(IDS.REALBOX).focus();
+
+ populateAutocompleteMatches(result.matches);
+ matchElBeingDeleted = null;
+
+ if (result.matches.length === 0) {
+ updateRealboxOutput({inline: '', text: ''});
+ return;
+ }
+
+ const firstMatch = autocompleteMatches[0];
+ if (firstMatch.allowedToBeDefaultMatch) {
+ const matchEls = Array.from($(IDS.REALBOX_MATCHES).children);
+ selectMatchEl(matchEls[0]);
+
+ const fill = firstMatch.fillIntoEdit;
+ const inline = firstMatch.inlineAutocompletion;
+ const textEnd = fill.length - inline.length;
+ updateRealboxOutput({
+ moveCursorToEnd: true,
+ inline: inline,
+ text: assert(fill.substr(0, textEnd)),
+ });
+ } else {
+ updateRealboxOutput({
+ moveCursorToEnd: true,
+ inline: '',
+ text: lastInput,
+ });
+ }
+}
+
/**
* Callback for embeddedSearch.newTabPage.ondeletecustomlinkdone. Called when
* the custom link was successfully deleted. Shows the "Shortcut deleted"
@@ -936,6 +1161,233 @@ function onMostVisitedChange() {
reloadTiles();
}
+/** @param {!AutocompleteResult} result */
+function onQueryAutocompleteDone(result) {
+ if (result.status === AutocompleteResultStatus.SKIPPED ||
+ result.input !== lastOutput.text) {
+ return; // Stale or skipped result; ignore.
+ }
+
+ populateAutocompleteMatches(result.matches);
+
+ if (result.matches.length === 0) {
+ return;
+ }
+
+ if (result.matches[0].allowedToBeDefaultMatch) {
+ selectMatchEl(assert($(IDS.REALBOX_MATCHES).firstElementChild));
+ }
+
+ // If the user is deleting content, don't quickly re-suggest the same
+ // output.
+ if (!isDeletingInput) {
+ const first = result.matches[0];
+ if (first.allowedToBeDefaultMatch && first.inlineAutocompletion) {
+ updateRealboxOutput({inline: first.inlineAutocompletion});
+ }
+ }
+}
+
+/** @param {!Event} e */
+function onRealboxCutCopy(e) {
+ const realboxEl = $(IDS.REALBOX);
+ if (!realboxEl.value || realboxEl.selectionStart !== 0 ||
+ realboxEl.selectionEnd !== realboxEl.value.length ||
+ autocompleteMatches.length === 0) {
+ // Only handle cut/copy when realbox has content and it's all selected.
+ return;
+ }
+
+ const matchEls = Array.from($(IDS.REALBOX_MATCHES).children);
+ const selected = matchEls.findIndex(matchEl => {
+ return matchEl.classList.contains(CLASSES.SELECTED);
+ });
+
+ const selectedMatch = autocompleteMatches[selected];
+ if (selectedMatch && !selectedMatch.isSearchType) {
+ e.clipboardData.setData('text/plain', selectedMatch.destinationUrl);
+ e.preventDefault();
+ if (e.type === 'cut') {
+ realboxEl.value = '';
+ }
+ }
+}
+
+function onRealboxInput() {
+ const realboxValue = $(IDS.REALBOX).value;
+
+ updateRealboxOutput({inline: '', text: realboxValue});
+
+ if (realboxValue.trim()) {
+ queryAutocomplete(realboxValue);
+ } else {
+ setRealboxMatchesVisible(false);
+ setRealboxWrapperListenForKeydown(false);
+ setAutocompleteMatches([]);
+ }
+}
+
+/** @param {Event} e */
+function onRealboxWrapperFocusIn(e) {
+ if (e.target.matches(`#${IDS.REALBOX}`) && !$(IDS.REALBOX).value) {
+ queryAutocomplete('');
+ } else if (e.target.matches(`#${IDS.REALBOX_MATCHES} *`)) {
+ let target = e.target;
+ while (target && target.nodeName !== 'A') {
+ target = target.parentNode;
+ }
+ if (!target) {
+ return;
+ }
+ const selectedIndex = selectMatchEl(target);
+ // It doesn't really make sense to use fillFromMatch() here as the focus
+ // change drops the selection (and is probably just noisy to
+ // screenreaders).
+ const newFill = autocompleteMatches[selectedIndex].fillIntoEdit;
+ updateRealboxOutput({moveCursorToEnd: true, inline: '', text: newFill});
+ }
+}
+
+/** @param {Event} e */
+function onRealboxWrapperFocusOut(e) {
+ const target = /** @type {Element} */ (e.target);
+ if (matchElBeingDeleted && matchElBeingDeleted.contains(target)) {
+ // When a match is being deleted, the focus gets dropped temporariliy as the
+ // element is deleted from the DOM. Don't stop autocomplete in those cases.
+ return;
+ }
+
+ const relatedTarget = /** @type {Element} */ (e.relatedTarget);
+ const realboxWrapper = $(IDS.REALBOX_INPUT_WRAPPER);
+ if (!realboxWrapper.contains(relatedTarget)) {
+ setRealboxMatchesVisible(false);
+ // Note: intentionally leaving keydown listening and match data intact.
+ window.chrome.embeddedSearch.searchBox.stopAutocomplete(
+ /*clearResult=*/ true);
+
+ // Clear the input if it was empty when displaying the matches.
+ if (lastInput === '') {
+ updateRealboxOutput({inline: '', text: ''});
+ }
+ }
+}
+
+/** @param {Event} e */
+function onRealboxWrapperKeydown(e) {
+ assert(autocompleteMatches.length > 0);
+
+ const key = e.key;
+
+ const realboxEl = $(IDS.REALBOX);
+ if (e.target === realboxEl && lastOutput.inline) {
+ const realboxValue = realboxEl.value;
+ const realboxSelected = realboxValue.substring(
+ realboxEl.selectionStart, realboxEl.selectionEnd);
+ // If the current state matches the default text + inline autocompletion
+ // and the user types the next key in the inline autocompletion, just move
+ // the selection and requery autocomplete. This is required to avoid flicker
+ // while setting .value and .selection{Start,End} to keep typing smooth.
+ if (realboxSelected === lastOutput.inline &&
+ realboxValue === lastOutput.text + lastOutput.inline &&
+ lastOutput.inline[0].toLocaleLowerCase() === key.toLocaleLowerCase()) {
+ updateRealboxOutput({
+ inline: lastOutput.inline.substr(1),
+ text: assert(lastOutput.text + key),
+ });
+ queryAutocomplete(lastOutput.text);
+ e.preventDefault();
+ return;
+ }
+ }
+
+ if (!REALBOX_KEYDOWN_HANDLED_KEYS.includes(key)) {
+ return;
+ }
+
+ const realboxMatchesEl = $(IDS.REALBOX_MATCHES);
+ const matchEls = Array.from(realboxMatchesEl.children);
+ const selected = matchEls.findIndex(matchEl => {
+ return matchEl.classList.contains(CLASSES.SELECTED);
+ });
+
+ if (key === 'Delete') {
+ if (e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) {
+ const selectedMatch = autocompleteMatches[selected];
+ if (selectedMatch && selectedMatch.supportsDeletion) {
+ matchElBeingDeleted = matchEls[selected];
+ window.chrome.embeddedSearch.searchBox.deleteAutocompleteMatch(
+ selected);
+ e.preventDefault();
+ }
+ }
+ return;
+ }
+
+ const hasMods = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;
+ if (hasMods && key !== 'Enter') {
+ return;
+ }
+
+ if (key === 'Enter') {
+ if (matchEls[selected] && matchEls.concat(realboxEl).includes(e.target)) {
+ // Note: dispatching a MouseEvent here instead of using e.g. .click() as
+ // this forwards key modifiers. This enables Shift+Enter to open a match
+ // in a new window, for example.
+ matchEls[selected].dispatchEvent(new MouseEvent('click', e));
+ e.preventDefault();
+ }
+ return;
+ }
+
+ if (!areRealboxMatchesVisible()) {
+ if (key === 'ArrowUp' || key === 'ArrowDown') {
+ setRealboxMatchesVisible(true);
+ e.preventDefault();
+ }
+ return;
+ }
+
+ if (key === 'Escape' && selected === 0) {
+ updateRealboxOutput({inline: '', text: ''});
+ setRealboxMatchesVisible(false);
+ setRealboxWrapperListenForKeydown(false);
+ setAutocompleteMatches([]);
+ e.preventDefault();
+ return;
+ }
+
+ /** @type {number} */ let newSelected;
+ if (key === 'ArrowDown') {
+ newSelected = selected + 1 < matchEls.length ? selected + 1 : 0;
+ } else if (key === 'ArrowUp') {
+ newSelected = selected - 1 >= 0 ? selected - 1 : matchEls.length - 1;
+ } else if (key === 'Escape' || key === 'PageUp') {
+ newSelected = 0;
+ } else if (key === 'PageDown') {
+ newSelected = matchEls.length - 1;
+ }
+ assert(selectMatchEl(assert(matchEls[newSelected])) >= 0);
+ e.preventDefault();
+
+ if (realboxMatchesEl.contains(document.activeElement)) {
+ // Selection should match focus if focus is currently in the matches.
+ matchEls[newSelected].focus();
+ }
+
+ const newMatch = autocompleteMatches[newSelected];
+ const newFill = newMatch.fillIntoEdit;
+ let newInline = '';
+ if (newMatch.allowedToBeDefaultMatch) {
+ newInline = newMatch.inlineAutocompletion;
+ }
+ const newFillEnd = newFill.length - newInline.length;
+ updateRealboxOutput({
+ moveCursorToEnd: true,
+ inline: newInline,
+ text: assert(newFill.substr(0, newFillEnd)),
+ });
+}
+
/**
* Handles a click on the restore all notification link by hiding the
* notification and informing Chrome.
@@ -958,6 +1410,9 @@ function onThemeChange() {
renderTheme();
renderOneGoogleBarTheme();
sendThemeInfoToMostVisitedIframe();
+ if ($(IDS.PROMO)) {
+ showPromoIfNotOverlapping();
+ }
}
/**
@@ -999,6 +1454,103 @@ function overrideExecutableTimeoutForTesting(timeout) {
}
/**
+ * @param {!Array<!AutocompleteMatch>} matches
+ */
+function populateAutocompleteMatches(matches) {
+ const realboxMatchesEl = document.createElement('div');
+ realboxMatchesEl.setAttribute('role', 'listbox');
+
+ for (let i = 0; i < matches.length; ++i) {
+ const match = matches[i];
+ const matchEl = document.createElement('a');
+ matchEl.href = match.destinationUrl;
+ matchEl.setAttribute('role', 'option');
+
+ if (match.isSearchType) {
+ const icon = document.createElement('div');
+ const isSearchHistory = SEARCH_HISTORY_MATCH_TYPES.includes(match.type);
+ icon.classList.add(
+ isSearchHistory ? CLASSES.CLOCK_ICON : CLASSES.SEARCH_ICON);
+ matchEl.appendChild(icon);
+ } else {
+ // TODO(crbug.com/997229): use chrome://favicon/<url> when perms allow.
+ const iconUrl = new URL('chrome-search://ntpicon/');
+ iconUrl.searchParams.set('show_fallback_monogram', 'false');
+ iconUrl.searchParams.set('size', '24@' + window.devicePixelRatio + 'x');
+ iconUrl.searchParams.set('url', match.destinationUrl);
+ matchEl.style.backgroundImage = 'url(' + iconUrl.toString() + ')';
+ }
+
+ const contentsEls =
+ renderMatchClassifications(match.contents, match.contentsClass);
+ const descriptionEls = [];
+ const separatorEls = [];
+ let separatorText = '';
+
+ if (match.description) {
+ descriptionEls.push(...renderMatchClassifications(
+ match.description, match.descriptionClass));
+ separatorText = configData.translatedStrings.realboxSeparator;
+ separatorEls.push(document.createTextNode(separatorText));
+ }
+
+ const ariaLabel = match.swapContentsAndDescription ?
+ match.description + separatorText + match.contents :
+ match.contents + separatorText + match.description;
+ matchEl.setAttribute('aria-label', ariaLabel);
+
+ const layout = match.swapContentsAndDescription ?
+ [descriptionEls, separatorEls, contentsEls] :
+ [contentsEls, separatorEls, descriptionEls];
+
+ for (const col of layout) {
+ col.forEach(colEl => matchEl.appendChild(colEl));
+ }
+
+ if (match.supportsDeletion && configData.suggestionTransparencyEnabled) {
+ const icon = document.createElement('button');
+ icon.title = configData.translatedStrings.removeSuggestion;
+ icon.classList.add(CLASSES.REMOVE_ICON);
+ icon.onmousedown = e => {
+ e.preventDefault(); // Stops default browser action (focus)
+ };
+ icon.onclick = e => {
+ matchElBeingDeleted = matchEl;
+ window.chrome.embeddedSearch.searchBox.deleteAutocompleteMatch(i);
+ e.preventDefault(); // Stops default browser action (navigation)
+ };
+
+ const remove = document.createElement('div');
+ remove.classList.add(CLASSES.REMOVE_MATCH);
+
+ remove.appendChild(icon);
+ matchEl.appendChild(remove);
+ realboxMatchesEl.classList.add(CLASSES.REMOVABLE);
+ }
+
+ realboxMatchesEl.append(matchEl);
+ }
+
+ $(IDS.REALBOX_MATCHES).remove();
+ realboxMatchesEl.id = IDS.REALBOX_MATCHES;
+
+ $(IDS.REALBOX_INPUT_WRAPPER).appendChild(realboxMatchesEl);
+
+ const hasMatches = matches.length > 0;
+ setRealboxMatchesVisible(hasMatches);
+ setRealboxWrapperListenForKeydown(hasMatches);
+ setAutocompleteMatches(matches);
+}
+
+/**
+ * @param {string} input
+ */
+function queryAutocomplete(input) {
+ lastInput = input;
+ window.chrome.embeddedSearch.searchBox.queryAutocomplete(input);
+}
+
+/**
* @param {!Element} element
* @param {!Array<string>} keys
* @param {!function(Event)} handler
@@ -1044,6 +1596,21 @@ function reloadTiles() {
}
/**
+ * @param {string} text
+ * @param {!Array<!ACMatchClassification>} classifications
+ * @return {!Array<!Element>}
+ */
+function renderMatchClassifications(text, classifications) {
+ return classifications.map((classification, i) => {
+ const classes = classificationStyleToClasses(classification.style);
+ const next = classifications[i + 1] || {offset: text.length};
+ const classifiedText = text.substring(classification.offset, next.offset);
+ return classes.length ? spanWithClasses(classifiedText, classes) :
+ document.createTextNode(classifiedText);
+ });
+}
+
+/**
* Updates the OneGoogleBar (if it is loaded) based on the current theme.
* TODO(crbug.com/918582): Add support for OGB dark mode.
*/
@@ -1071,29 +1638,14 @@ function renderTheme() {
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(
@@ -1103,14 +1655,22 @@ function renderTheme() {
// 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);
+ const isDefaultBackground = info.usingDefaultTheme && !info.imageUrl;
document.body.classList.toggle(CLASSES.USE_NOTIFIER, !isDefaultBackground);
- updateThemeAttribution(info.attributionUrl, info.imageHorizontalAlignment);
- setCustomThemeStyle(info);
+ // 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 = [
+ convertToRGBAColor(info.backgroundColorRgba), info.imageUrl,
+ info.imageTiling, info.imageHorizontalAlignment,
+ info.imageVerticalAlignment
+ ].join(' ').trim();
- if (info.customBackgroundConfigured) {
+ $(IDS.CUSTOM_BG).style.opacity = '0';
+ $(IDS.CUSTOM_BG).style.backgroundImage = '';
+ customize.clearAttribution();
+ } else {
// Do anything only if the custom background changed.
const imageUrl = assert(info.imageUrl);
if (!$(IDS.CUSTOM_BG).style.backgroundImage.includes(imageUrl)) {
@@ -1140,12 +1700,11 @@ function renderTheme() {
'' + info.attribution1, '' + info.attribution2,
'' + info.attributionActionUrl);
}
- } else {
- $(IDS.CUSTOM_BG).style.opacity = '0';
- $(IDS.CUSTOM_BG).style.backgroundImage = '';
- customize.clearAttribution();
}
+ updateThemeAttribution(info.attributionUrl, info.imageHorizontalAlignment);
+ setCustomThemeStyle(info);
+
$(customize.IDS.RESTORE_DEFAULT)
.classList.toggle(
customize.CLASSES.OPTION_DISABLED, !info.customBackgroundConfigured);
@@ -1200,6 +1759,23 @@ function requestAndInsertGoogleResources() {
}
}
+/**
+ * @param {!EventTarget} elToSelect
+ * @return {number} The selected index (if found); else -1.
+ */
+function selectMatchEl(elToSelect) {
+ let selectedIndex = -1;
+ Array.from($(IDS.REALBOX_MATCHES).children).forEach((matchEl, i) => {
+ const found = matchEl === elToSelect;
+ matchEl.classList.toggle(CLASSES.SELECTED, found);
+ matchEl.setAttribute('aria-selected', found);
+ if (found) {
+ selectedIndex = i;
+ }
+ });
+ return selectedIndex;
+}
+
/** Sends the current theme info to the most visited iframe. */
function sendThemeInfoToMostVisitedIframe() {
const info = getThemeBackgroundInfo();
@@ -1236,6 +1812,11 @@ function setAttributionVisibility(show) {
$(IDS.ATTRIBUTION).style.display = show ? '' : 'none';
}
+/** @param {!Array<!AutocompleteMatch>} matches */
+function setAutocompleteMatches(matches) {
+ autocompleteMatches = matches;
+}
+
/**
* Updates the NTP style according to theme.
* @param {Object} themeInfo The information about the theme.
@@ -1250,9 +1831,6 @@ function setCustomThemeStyle(themeInfo) {
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);
}
@@ -1278,6 +1856,21 @@ function setFakeboxVisibility(show) {
document.body.classList.toggle(CLASSES.HIDE_FAKEBOX, !show);
}
+/** @param {boolean} visible */
+function setRealboxMatchesVisible(visible) {
+ $(IDS.REALBOX_INPUT_WRAPPER).classList.toggle(CLASSES.SHOW_MATCHES, visible);
+}
+
+/** @param {boolean} listen */
+function setRealboxWrapperListenForKeydown(listen) {
+ const realboxWrapper = $(IDS.REALBOX_INPUT_WRAPPER);
+ if (listen) {
+ realboxWrapper.addEventListener('keydown', onRealboxWrapperKeydown);
+ } else {
+ realboxWrapper.removeEventListener('keydown', onRealboxWrapperKeydown);
+ }
+}
+
/**
* 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,
@@ -1315,6 +1908,63 @@ function showNotification(msg) {
$(IDS.UNDO_LINK).focus();
}
+function showPromoIfNotOverlapping() {
+ $(IDS.PROMO).style.visibility = isPromoOverlapping() ? 'hidden' : 'visible';
+}
+
+function showPromoIfNotOverlappingAndTrackResizes() {
+ showPromoIfNotOverlapping();
+ // The removal before addition is to ensure only 1 event listener is ever
+ // active at the same time.
+ window.removeEventListener('resize', showPromoIfNotOverlapping);
+ window.addEventListener('resize', showPromoIfNotOverlapping);
+}
+
+/**
+ * @param {string} text
+ * @param {!Array<string>} classes
+ * @return {!Element}
+ */
+function spanWithClasses(text, classes) {
+ const span = document.createElement('span');
+ span.classList.add(...classes);
+ span.textContent = text;
+ return span;
+}
+
+/** @param {!RealboxOutputUpdate} update */
+function updateRealboxOutput(update) {
+ assert(Object.keys(update).length > 0);
+
+ const realboxEl = $(IDS.REALBOX);
+ const newOutput =
+ /** @type {!RealboxOutput} */ (Object.assign({}, lastOutput, update));
+ const newAll = newOutput.text + newOutput.inline;
+
+ const inlineDiffers = newOutput.inline !== lastOutput.inline;
+ const preserveSelection = !inlineDiffers && !update.moveCursorToEnd;
+ let needsSelectionUpdate = !preserveSelection;
+
+ const oldSelectionStart = realboxEl.selectionStart;
+
+ if (newAll !== realboxEl.value) {
+ realboxEl.value = newAll;
+ needsSelectionUpdate = true; // Setting .value blows away selection.
+ }
+
+ if (newAll.trim() && needsSelectionUpdate) {
+ realboxEl.selectionStart =
+ preserveSelection ? oldSelectionStart : newOutput.text.length;
+ // If the selection shouldn't be preserved, set the selection end to the
+ // same as the selection start (i.e. drop selection but move cursor).
+ realboxEl.selectionEnd =
+ preserveSelection ? oldSelectionStart : newAll.length;
+ }
+
+ isDeletingInput = userDeletedOutput(lastOutput, newOutput);
+ lastOutput = newOutput;
+}
+
/**
* Renders the attribution if the URL is present, otherwise hides it.
* @param {string|undefined} url The URL of the attribution image, if any.
@@ -1342,6 +1992,17 @@ function updateThemeAttribution(url, themeBackgroundAlignment) {
setAttributionVisibility(true);
}
+/**
+ * @param {!RealboxOutput} before
+ * @param {!RealboxOutput} after
+ * @return {boolean}
+ */
+function userDeletedOutput(before, after) {
+ const beforeAll = before.text + before.inline;
+ const afterAll = after.text + after.inline;
+ return beforeAll.length > afterAll.length && beforeAll.startsWith(afterAll);
+}
+
return {
init: init, // Exposed for testing.
listen: listen,
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp_common.css b/chromium/chrome/browser/resources/local_ntp/local_ntp_common.css
index 102d85b4595..0f89aa12292 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp_common.css
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp_common.css
@@ -5,7 +5,7 @@
html {
/* Material Design colors. Keep in sync with ui/gfx/color_palette.h. */
- --dark-mode-bg-rgb: 50, 54, 57;
+ --dark-mode-bg-rgb: 53, 54, 58;
--dark-mode-dialog-rgb: 41, 42, 45;
/* Google Grey */
diff --git a/chromium/chrome/browser/resources/local_ntp/local_ntp_resources.grd b/chromium/chrome/browser/resources/local_ntp/local_ntp_resources.grd
index ade6f647ab8..f4b535827d9 100644
--- a/chromium/chrome/browser/resources/local_ntp/local_ntp_resources.grd
+++ b/chromium/chrome/browser/resources/local_ntp/local_ntp_resources.grd
@@ -27,6 +27,8 @@
<include name="IDR_LOCAL_NTP_UTILS_JS" file="utils.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_LOCAL_NTP_VOICE_CSS" file="voice.css" flattenhtml="true" type="BINDATA" />
<include name="IDR_LOCAL_NTP_VOICE_JS" file="voice.js" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_MOST_VISITED_DONT_SHOW_PNG" file="icons\dont_show.png" type="BINDATA" />
+ <include name="IDR_MOST_VISITED_DONT_SHOW_2X_PNG" file="icons\dont_show_2x.png" type="BINDATA" />
<include name="IDR_MOST_VISITED_IFRAME_CSS" file="most_visited_iframe.css" type="BINDATA" />
<include name="IDR_MOST_VISITED_SINGLE_CSS" file="most_visited_single.css" type="BINDATA" />
<include name="IDR_MOST_VISITED_SINGLE_HTML" file="most_visited_single.html" type="BINDATA" />
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 995e9a8b6b6..d1ed09f7a96 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -54,32 +54,11 @@ a:visited {
#mv-tiles,
.mv-tiles-old {
- display: flex;
- flex-wrap: wrap;
font-size: 0;
- justify-content: center;
- /* 5 112px tiles per row. If you change this, also change the corresponding
- * values in local_ntp.css. */
- max-width: calc(var(--md-tile-size) * var(--md-max-tiles-row));
opacity: 0;
- position: static;
- /* This align correctly for both LTR and RTL */
- text-align: -webkit-auto;
- user-select: none;
-}
-
-body.grid-layout #mv-tiles,
-body.grid-layout .mv-tiles-old {
- display: block;
- flex-wrap: unset;
- justify-content: unset;
- max-width: unset;
position: relative;
- text-align: unset;
-}
-
-html:not(.no-initial-fade) :-webkit-any(#mv-tiles, .mv-tiles-old) {
transition: opacity 300ms;
+ user-select: none;
}
.mv-tiles-old {
@@ -104,11 +83,11 @@ html:not(.no-initial-fade) :-webkit-any(#mv-tiles, .mv-tiles-old) {
/* Prevent transitions on the held tile in order for it to smoothly follow the
* mouse. */
-.grid-reorder .grid-tile {
+.reorder .grid-tile {
transition-duration: 0s;
}
-.grid-reorder {
+.reorder {
z-index: 10; /* Ensure the held tile is visible. */
}
@@ -127,46 +106,24 @@ html:not(.no-initial-fade) :-webkit-any(#mv-tiles, .mv-tiles-old) {
width: var(--md-tile-size);
}
-.reorder {
- background-color: white;
- border-radius: 4px;
- box-shadow: 0 1px 3px 0 rgba(var(--GG800-rgb), .3),
- 0 4px 8px 3px rgba(var(--GG800-rgb), .15);
- color: rgb(var(--GG800-rgb));
- transition-duration: 200ms;
-}
-
-@media (prefers-color-scheme: dark) {
- .reorder {
- background-color: rgb(var(--dark-mode-bg-rgb));
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .4),
- 0 4px 8px 3px rgba(0, 0, 0, .25);
- color: rgb(var(--GG100-rgb));
- }
-}
-
-.reorder .md-tile-inner {
- z-index: unset;
-}
-
.md-empty-tile {
display: none;
}
body:not(.reordering) .md-tile:hover,
-.grid-reorder .md-tile {
+.reorder .md-tile {
background-color: rgba(var(--GG900-rgb), .06);
}
@media (prefers-color-scheme: dark) {
body:not(.reordering) .md-tile:hover,
- .grid-reorder .md-tile {
+ .reorder .md-tile {
background-color: rgba(255, 255, 255, .1);
}
}
body.dark-theme:not(.reordering) .md-tile:hover,
-body.dark-theme .grid-reorder .md-tile {
+body.dark-theme .reorder .md-tile {
background-color: rgba(255, 255, 255, .1);
}
@@ -257,7 +214,7 @@ body.mac-chromeos .md-title {
}
/* Apply when a custom background is set. */
-body.custom-background .md-tile:not(.reorder) .md-title {
+body.custom-background .md-title {
filter: drop-shadow(0 0 6px rgba(0, 0, 0, .35));
}
@@ -266,12 +223,9 @@ body.use-title-container .md-title {
background-color: white;
/* Necessary for a "pill" shape. Using 50% creates an oval. */
border-radius: 500px;
- padding: 0 8px;
-}
-
-body.use-title-container .md-tile:not(.reorder) {
color: rgb(var(--GG800-rgb));
filter: unset;
+ padding: 0 8px;
}
.md-menu {
@@ -300,9 +254,10 @@ body:not(.reordering) .md-menu:focus:not(.mouse-navigation) {
/* We use ::after without content to provide the masked X element. */
.md-menu::after {
--mask-width: calc(var(--md-menu-size) - 2);
+ /* TODO(crbug.com/1012065): Use SVG for the "X" icon. */
-webkit-mask-image: -webkit-image-set(
- url(chrome-search://local-ntp/images/close_3_mask.png) 1x,
- url(chrome-search://local-ntp/images/close_3_mask.png@2x) 2x);
+ url(chrome-search://most-visited/dont_show.png) 1x,
+ url(chrome-search://most-visited/dont_show_2x.png) 2x);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: var(--mask-width);
background-color: rgb(var(--GG600-rgb));
@@ -345,13 +300,13 @@ body:not(.reordering) .md-menu:focus::after {
}
}
-body.dark-theme .md-tile:not(.reorder) .md-menu::after,
+body.dark-theme .md-tile .md-menu::after,
body.dark-theme:not(.reordering) .md-menu:focus:not(.mouse-navigation)::after {
background-color: white;
}
@media (prefers-color-scheme: dark) {
- body.dark-theme .md-tile:not(.reorder) .md-menu::after,
+ body.dark-theme .md-tile .md-menu::after,
body.dark-theme:not(.reordering)
.md-menu:focus:not(.mouse-navigation)::after {
background-color: rgb(var(--GG200-rgb));
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 9d8db297c9a..0fa5b62d10b 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.html
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.html
@@ -1,5 +1,5 @@
<!doctype html>
-<html class="$i18n{noInitialFade}">
+<html>
<!-- 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. -->
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 c497599fdb4..1fe5765c7fd 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -46,9 +46,6 @@ const IDS = {
*/
const CLASSES = {
FAILED_FAVICON: 'failed-favicon', // Applied when the favicon fails to load.
- GRID_LAYOUT: 'grid-layout',
- // Applied to the grid tile being moved while reordering.
- GRID_REORDER: 'grid-reorder',
GRID_TILE: 'grid-tile',
GRID_TILE_CONTAINER: 'grid-tile-container',
REORDER: 'reorder', // Applied to the tile being moved while reordering.
@@ -56,7 +53,6 @@ const CLASSES = {
REORDERING: 'reordering',
MAC_CHROMEOS: 'mac-chromeos', // Reduces font weight for MacOS and ChromeOS.
// Material Design classes.
- MD_EMPTY_TILE: 'md-empty-tile',
MD_FALLBACK_LETTER: 'md-fallback-letter',
MD_ICON: 'md-icon',
MD_ADD_ICON: 'md-add-icon',
@@ -65,7 +61,6 @@ const CLASSES = {
MD_TILE: 'md-tile',
MD_TILE_INNER: 'md-tile-inner',
MD_TITLE: 'md-title',
- NO_INITIAL_FADE: 'no-initial-fade',
};
/**
@@ -96,8 +91,6 @@ const TileVisualType = {
ICON_REAL: 1,
ICON_COLOR: 2,
ICON_DEFAULT: 3,
- THUMBNAIL: 7,
- THUMBNAIL_FAILED: 8,
};
/**
@@ -114,6 +107,12 @@ const RESIZE_TIMEOUT_DELAY = 66;
const MD_MAX_NUM_CUSTOM_LINK_TILES = 10;
/**
+ * Maximum number of tiles if Most Visited is enabled.
+ * @const {number}
+ */
+const MD_MAX_NUM_MOST_VISITED_TILES = 8;
+
+/**
* Maximum number of tiles per row for Material Design.
* @const {number}
*/
@@ -142,8 +141,8 @@ const MD_TILE_WIDTH = 112;
const MD_NUM_TILES_ALWAYS_VISIBLE = 6;
/**
- * The origin of this request, i.e. 'https://www.google.TLD' for the remote NTP,
- * or 'chrome-search://local-ntp' for the local NTP.
+ * The origin of this request, i.e. 'chrome-search://local-ntp' for the local
+ * NTP.
* @const {string}
*/
const DOMAIN_ORIGIN = '{{ORIGIN}}';
@@ -163,34 +162,12 @@ let loadedCounter = 1;
let tiles = null;
/**
- * Maximum number of MostVisited tiles to show at any time. If the host page
- * doesn't send enough tiles and custom links is not enabled, we fill them blank
- * tiles. This can be changed depending on what feature is enabled. Set by the
- * host page, while 8 is default.
- * @type {number}
- */
-let maxNumTiles = 8;
-
-/**
* List of parameters passed by query args.
* @type {Object}
*/
let queryArgs = {};
/**
- * True if we are currently reordering the tiles.
- * @type {boolean}
- */
-let reordering = false;
-
-/**
- * The tile that is being moved during the reorder flow. Null if we are
- * currently not reordering.
- * @type {?Element}
- */
-let elementToReorder = null;
-
-/**
* True if the custom links feature is enabled, i.e. when this is a Google NTP.
* Set when the iframe is initialized.
* @type {boolean}
@@ -198,26 +175,12 @@ let elementToReorder = null;
let customLinksFeatureEnabled = false;
/**
- * True if the grid layout is enabled.
- * @type {boolean}
- */
-let isGridEnabled = false;
-
-/**
* The current grid of tiles.
* @type {?Grid}
*/
let currGrid = null;
/**
- * Called by tests to enable the grid layout.
- */
-function enableGridLayoutForTesting() {
- isGridEnabled = true;
- document.body.classList.add(CLASSES.GRID_LAYOUT);
-}
-
-/**
* Additional API for Array. Moves the item at index |from| to index |to|.
* @param {number} from Index of the item to move.
* @param {number} to Index to move the item to.
@@ -296,17 +259,13 @@ class Grid {
this.tilesAlwaysVisible_ =
params.tilesAlwaysVisible || MD_NUM_TILES_ALWAYS_VISIBLE;
this.maxTilesPerRow_ = params.maxTilesPerRow || MD_MAX_TILES_PER_ROW;
- this.maxTiles_ = params.maxTiles || maxNumTiles;
+ this.maxTiles_ = params.maxTiles || getMaxNumTiles();
this.maxTilesPerRowWindow_ = this.getMaxTilesPerRow_();
this.tiles_ =
this.container_.getElementsByClassName(CLASSES.GRID_TILE_CONTAINER);
- if (this.tiles_.length > this.maxTiles_) {
- throw new Error(
- 'The number of tiles (' + this.tiles_.length +
- ') exceeds the maximum (' + this.maxTiles_ + ').');
- }
+ // Ignore any tiles past the maximum allowed.
this.position_ = new Array(this.maxTiles_);
this.order_ = new Array(this.maxTiles_);
for (let i = 0; i < this.maxTiles_; i++) {
@@ -557,7 +516,7 @@ class Grid {
this.newIndexOfItemToReorder_ = index;
// Apply reorder styling.
- tile.classList.add(CLASSES.GRID_REORDER);
+ tile.classList.add(CLASSES.REORDER);
// Disable other hover/active styling for all tiles.
document.body.classList.add(CLASSES.REORDERING);
@@ -609,7 +568,7 @@ class Grid {
const index = Number(tile.getAttribute('index'));
// Remove reorder styling.
- tile.classList.remove(CLASSES.GRID_REORDER);
+ tile.classList.remove(CLASSES.REORDER);
document.body.classList.remove(CLASSES.REORDERING);
// Move the tile to its new position and notify EmbeddedSearchAPI that the
@@ -634,7 +593,7 @@ class Grid {
reorderToIndexAtPoint_(x, y) {
const elements = document.elementsFromPoint(x, y);
for (let i = 0; i < elements.length; i++) {
- if (elements[i].classList.contains('grid-tile-container') &&
+ if (elements[i].classList.contains(CLASSES.GRID_TILE_CONTAINER) &&
elements[i].getAttribute('index') !== null) {
this.reorderToIndex_(Number(elements[i].getAttribute('index')));
return;
@@ -737,7 +696,7 @@ function logEvent(eventType) {
/**
* Log impression of an NTP tile.
- * @param {number} tileIndex Position of the tile, >= 0 and < |maxNumTiles|.
+ * @param {number} tileIndex Position of the tile, >= 0 and < getMaxNumTiles().
* @param {number} tileTitleSource The source of the tile's title as received
* from getMostVisitedItemData.
* @param {number} tileSource The tile's source as received from
@@ -754,7 +713,7 @@ function logMostVisitedImpression(
/**
* Log click on an NTP tile.
- * @param {number} tileIndex Position of the tile, >= 0 and < |maxNumTiles|.
+ * @param {number} tileIndex Position of the tile, >= 0 and < getMaxNumTiles().
* @param {number} tileTitleSource The source of the tile's title as received
* from getMostVisitedItemData.
* @param {number} tileSource The tile's source as received from
@@ -771,6 +730,7 @@ function logMostVisitedNavigation(
/**
* Returns true if custom links are enabled.
+ * @return {boolean}
*/
function isCustomLinksEnabled() {
return customLinksFeatureEnabled &&
@@ -778,6 +738,16 @@ function isCustomLinksEnabled() {
}
/**
+ * Returns the maximum number of tiles to show at any time. This can be changed
+ * depending on what feature is enabled.
+ * @return {number}
+ */
+function getMaxNumTiles() {
+ return isCustomLinksEnabled() ? MD_MAX_NUM_CUSTOM_LINK_TILES :
+ MD_MAX_NUM_MOST_VISITED_TILES;
+}
+
+/**
* Down counts the DOM elements that we are waiting for the page to load.
* When we get to 0, we send a message to the parent window.
* This is usually used as an EventListener of onload/onerror.
@@ -895,9 +865,8 @@ function removeAllOldTiles() {
}
/**
- * Called when all tiles have finished loading (successfully or not), including
- * their thumbnail images, and we are ready to show the new tiles and drop the
- * old ones.
+ * Called when all tiles have finished loading (successfully or not), and we are
+ * ready to show the new tiles and drop the old ones.
*/
function swapInNewTiles() {
// Store the tiles on the current closure.
@@ -905,7 +874,7 @@ function swapInNewTiles() {
// Add an "add new custom link" button if we haven't reached the maximum
// number of tiles.
- if (isCustomLinksEnabled() && cur.childNodes.length < maxNumTiles) {
+ if (isCustomLinksEnabled() && cur.childNodes.length < getMaxNumTiles()) {
const data = {
'rid': -1,
'title': queryArgs['addLink'],
@@ -915,7 +884,7 @@ function swapInNewTiles() {
'tileSource': -1,
'tileTitleSource': -1
};
- tiles.appendChild(renderMaterialDesignTile(data));
+ tiles.appendChild(renderTile(data));
}
const parent = document.querySelector('#' + IDS.MOST_VISITED);
@@ -937,18 +906,9 @@ function swapInNewTiles() {
cur.id = IDS.MV_TILES;
parent.appendChild(cur);
- if (isGridEnabled) {
- // Initialize the new tileset before modifying opacity. This will prevent
- // the transform transition from applying after the tiles fade in.
- currGrid.init(cur);
- } else {
- // Re-balance the tiles if there are more than |MD_MAX_TILES_PER_ROW| in
- // order to make even rows.
- if (cur.childNodes.length > MD_MAX_TILES_PER_ROW) {
- cur.style.maxWidth = 'calc(var(--md-tile-size) * ' +
- Math.ceil(cur.childNodes.length / 2) + ')';
- }
- }
+ // Initialize the new tileset before modifying opacity. This will prevent the
+ // transform transition from applying after the tiles fade in.
+ currGrid.init(cur);
const flushOpacity = () => window.getComputedStyle(cur).opacity;
@@ -957,11 +917,6 @@ function swapInNewTiles() {
flushOpacity();
cur.style.opacity = 1.0;
- if (document.documentElement.classList.contains(CLASSES.NO_INITIAL_FADE)) {
- flushOpacity();
- document.documentElement.classList.remove(CLASSES.NO_INITIAL_FADE);
- }
-
// Make sure the tiles variable contain the next tileset we'll use if the host
// page sends us an updated set of tiles.
tiles = document.createElement('div');
@@ -989,27 +944,25 @@ function updateTileVisibility() {
/**
* Handler for the 'show' message from the host page, called when it wants to
* add a suggestion tile.
- * It's also used to fill up our tiles to |maxNumTiles| if necessary.
- * @param {?MostVisitedData} args Data for the tile to be rendered.
+ * @param {!MostVisitedData} args Data for the tile to be rendered.
*/
function addTile(args) {
- if (isFinite(args.rid)) {
- // An actual suggestion. Grab the data from the embeddedSearch API.
- const data =
- chrome.embeddedSearch.newTabPage.getMostVisitedItemData(args.rid);
- if (!data) {
- return;
- }
+ if (!isFinite(args.rid)) {
+ return;
+ }
- if (!data.faviconUrl) {
- data.faviconUrl = 'chrome-search://favicon/size/16@' +
- window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.rid;
- }
- tiles.appendChild(renderTile(data));
- } else {
- // An empty tile
- tiles.appendChild(renderTile(null));
+ // Grab the tile's data from the embeddedSearch API.
+ const data =
+ chrome.embeddedSearch.newTabPage.getMostVisitedItemData(args.rid);
+ if (!data) {
+ return;
+ }
+
+ if (!data.faviconUrl) {
+ data.faviconUrl = 'chrome-search://favicon/size/16@' +
+ window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.rid;
}
+ tiles.appendChild(renderTile(data));
}
/**
@@ -1045,105 +998,15 @@ function editCustomLink(rid) {
}
/**
- * Starts the reorder flow. Updates the visual style of the held tile to
- * indicate that it is being moved.
- * @param {!Element} tile Tile that is being moved.
- */
-function startReorder(tile) {
- reordering = true;
- elementToReorder = tile;
-
- tile.classList.add(CLASSES.REORDER);
- // Disable other hover/active styling for all tiles.
- document.body.classList.add(CLASSES.REORDERING);
-
- document.addEventListener('dragend', () => {
- stopReorder(tile);
- }, {once: true});
-}
-
-/**
- * Stops the reorder flow. Resets the held tile's visual style and tells the
- * EmbeddedSearchAPI that a tile has been moved.
- * @param {!Element} tile Tile that has been moved.
- */
-function stopReorder(tile) {
- reordering = false;
- elementToReorder = null;
-
- tile.classList.remove(CLASSES.REORDER);
- document.body.classList.remove(CLASSES.REORDERING);
-
- // Update |data-pos| for all tiles and notify EmbeddedSearchAPI that the tile
- // has been moved.
- const allTiles = document.querySelectorAll('#mv-tiles .' + CLASSES.MD_TILE);
- for (let i = 0; i < allTiles.length; i++) {
- allTiles[i].setAttribute('data-pos', i);
- }
- chrome.embeddedSearch.newTabPage.reorderCustomLink(
- Number(tile.getAttribute('data-rid')),
- Number(tile.getAttribute('data-pos')));
-}
-
-/**
- * Sets up event listeners necessary for tile reordering.
- * @param {!Element} tile Tile on which to set the event listeners.
- */
-function setupReorder(tile) {
- // Starts the reorder flow.
- tile.addEventListener('dragstart', (event) => {
- if (!reordering) {
- startReorder(tile);
- }
- });
-
- tile.addEventListener('dragover', (event) => {
- // Only executed when the reorder flow is ongoing. Inserts the tile that is
- // being moved before/after this |tile| according to order in the list.
- if (reordering && elementToReorder && elementToReorder != tile) {
- // Determine which side to insert the element on:
- // - If the held tile comes after the current tile, insert behind the
- // current tile.
- // - If the held tile comes before the current tile, insert in front of
- // the current tile.
- let insertBefore; // Element to insert the held tile behind.
- if (tile.compareDocumentPosition(elementToReorder) &
- Node.DOCUMENT_POSITION_FOLLOWING) {
- insertBefore = tile;
- } else {
- insertBefore = tile.nextSibling;
- }
- $('mv-tiles').insertBefore(elementToReorder, insertBefore);
- }
- });
-}
-
-/**
- * Renders a MostVisited tile to the DOM.
- * @param {?MostVisitedData} data Object containing rid, url, title, favicon,
- * thumbnail, and optionally isAddButton. isAddButton is true if you want to
- * construct an add custom link button. data is null if you want to
- * construct an empty tile. isAddButton can only be set if custom links is
+ * Renders a MostVisited tile (i.e. shortcut) to the DOM.
+ * @param {!MostVisitedData} data Object containing rid, url, title, favicon,
+ * and optionally isAddButton. isAddButton is true if you want to construct
+ * an add custom link button, and can only be set if custom links is
* enabled.
- */
-function renderTile(data) {
- return renderMaterialDesignTile(data);
-}
-
-/**
- * Renders a MostVisited tile with Material Design styles.
- * @param {?MostVisitedData} data Object containing rid, url, title, favicon,
- * and optionally isAddButton. isAddButton is if you want to construct an
- * add custom link button. data is null if you want to construct an empty
- * tile.
* @return {Element}
*/
-function renderMaterialDesignTile(data) {
+function renderTile(data) {
const mdTile = document.createElement('a');
- if (data == null) {
- mdTile.className = CLASSES.MD_EMPTY_TILE;
- return mdTile;
- }
mdTile.className = CLASSES.MD_TILE;
// The tile will be appended to |tiles|.
@@ -1297,16 +1160,7 @@ function renderMaterialDesignTile(data) {
mdTile.appendChild(mdMenu);
}
- if (isGridEnabled) {
- return currGrid.createGridTile(mdTile, data.rid, !!data.isAddButton);
- } else {
- // Enable reordering.
- if (isCustomLinksEnabled() && !data.isAddButton) {
- mdTile.draggable = 'true';
- setupReorder(mdTile);
- }
- return mdTile;
- }
+ return currGrid.createGridTile(mdTile, data.rid, !!data.isAddButton);
}
/**
@@ -1316,7 +1170,7 @@ function init() {
// Create a new DOM element to hold the tiles. The tiles will be added
// one-by-one via addTile, and the whole thing will be inserted into the page
// in swapInNewTiles, after the parent has sent us the 'show' message, and all
- // thumbnails and favicons have loaded.
+ // favicons have loaded.
tiles = document.createElement('div');
// Parse query arguments.
@@ -1342,17 +1196,6 @@ function init() {
customLinksFeatureEnabled = true;
}
- // Enable grid layout.
- if (queryArgs['enableGrid'] == '1') {
- isGridEnabled = true;
- document.body.classList.add(CLASSES.GRID_LAYOUT);
- }
-
- // Set the maximum number of tiles to show.
- if (isCustomLinksEnabled()) {
- maxNumTiles = MD_MAX_NUM_CUSTOM_LINK_TILES;
- }
-
currGrid = new Grid();
// Set up layout updates on window resize. Throttled according to
// |RESIZE_TIMEOUT_DELAY|.
@@ -1363,11 +1206,7 @@ function init() {
}
resizeTimeout = window.setTimeout(() => {
resizeTimeout = null;
- if (isGridEnabled) {
- currGrid.onResize();
- } else {
- updateTileVisibility();
- }
+ currGrid.onResize();
}, RESIZE_TIMEOUT_DELAY);
};
@@ -1384,7 +1223,6 @@ function listen() {
return {
Grid: Grid, // Exposed for testing.
init: init, // Exposed for testing.
- enableGridLayoutForTesting: enableGridLayoutForTesting,
listen: listen,
};
}
diff --git a/chromium/chrome/browser/resources/management/BUILD.gn b/chromium/chrome/browser/resources/management/BUILD.gn
index 82dfd3d4cd9..4e27e412b9f 100644
--- a/chromium/chrome/browser/resources/management/BUILD.gn
+++ b/chromium/chrome/browser/resources/management/BUILD.gn
@@ -3,8 +3,10 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
deps = [
":management_browser_proxy",
":management_ui",
@@ -13,15 +15,34 @@ js_type_check("closure_compile") {
js_library("management_ui") {
deps = [
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:i18n_behavior",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:web_ui_listener_behavior",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:i18n_behavior.m",
+ "//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
js_library("management_browser_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
+ ]
+}
+
+polymer_modulizer("management_ui") {
+ js_file = "management_ui.js"
+ html_file = "management_ui.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("icons") {
+ js_file = "icons.js"
+ html_file = "icons.html"
+ html_type = "v3-ready"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":icons_module",
+ ":management_ui_module",
]
}
diff --git a/chromium/chrome/browser/resources/management/icons.html b/chromium/chrome/browser/resources/management/icons.html
index 2311bf2ec29..e6a075711d8 100644
--- a/chromium/chrome/browser/resources/management/icons.html
+++ b/chromium/chrome/browser/resources/management/icons.html
@@ -1,9 +1,4 @@
-<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">
-
<!-- Set of the management specific icons -->
-
<iron-iconset-svg name="management" size="24">
<svg>
<defs>
diff --git a/chromium/chrome/browser/resources/management/icons.js b/chromium/chrome/browser/resources/management/icons.js
new file mode 100644
index 00000000000..02ab37aaf4d
--- /dev/null
+++ b/chromium/chrome/browser/resources/management/icons.js
@@ -0,0 +1,10 @@
+// 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 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const template = html`{__html_template__}`;
+document.head.appendChild(template.content);
diff --git a/chromium/chrome/browser/resources/management/management.html b/chromium/chrome/browser/resources/management/management.html
index 8b4f15545d9..aea7f12bb74 100644
--- a/chromium/chrome/browser/resources/management/management.html
+++ b/chromium/chrome/browser/resources/management/management.html
@@ -7,7 +7,6 @@
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
- <link rel="import" href="chrome://resources/html/cr.html">
<style>
html {
background: var(--md-background-color);
@@ -30,8 +29,7 @@
}
</style>
- <link rel="import" href="management_ui.html">
- <script src="strings.js"></script>
+ <script type="module" src="management_ui.js"></script>
</head>
<body>
<management-ui></management-ui>
diff --git a/chromium/chrome/browser/resources/management/management_browser_proxy.html b/chromium/chrome/browser/resources/management/management_browser_proxy.html
deleted file mode 100644
index abaff4208aa..00000000000
--- a/chromium/chrome/browser/resources/management/management_browser_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="management_browser_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/management/management_browser_proxy.js b/chromium/chrome/browser/resources/management/management_browser_proxy.js
index a86bbaa7b15..9c5614071dd 100644
--- a/chromium/chrome/browser/resources/management/management_browser_proxy.js
+++ b/chromium/chrome/browser/resources/management/management_browser_proxy.js
@@ -2,166 +2,156 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('management', function() {
- /**
- * @typedef {{
- * name: string,
- * permissions: !Array<string>
- * }}
- */
- let Extension;
-
- /** @enum {string} */
- const ReportingType = {
- SECURITY: 'security',
- DEVICE: 'device',
- USER: 'user',
- USER_ACTIVITY: 'user-activity',
- EXTENSIONS: 'extensions'
- };
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+
+/**
+ * @typedef {{
+ * name: string,
+ * permissions: !Array<string>
+ * }}
+ */
+export let Extension;
+
+/** @enum {string} */
+export const ReportingType = {
+ SECURITY: 'security',
+ DEVICE: 'device',
+ USER: 'user',
+ USER_ACTIVITY: 'user-activity',
+ EXTENSIONS: 'extensions'
+};
+
+/**
+ * @typedef {{
+ * messageId: string,
+ * reportingType: !ReportingType,
+ * }}
+ */
+export let BrowserReportingResponse;
+
+/**
+ * @typedef {{
+ * browserManagementNotice: string,
+ * extensionReportingTitle: string,
+ * pageSubtitle: string,
+ * managed: boolean,
+ * overview: string,
+ * customerLogo: string,
+ * threatProtectionDescription: string
+ * }}
+ */
+let ManagedDataResponse;
+
+/**
+ * @typedef {{
+ * title: string,
+ * permission: string
+ * }}
+ */
+let ThreatProtectionPermission;
+
+/**
+ * @typedef {{
+ * info: !Array<!ThreatProtectionPermission>,
+ * description: string
+ * }}
+ */
+export let ThreatProtectionInfo;
+
+// <if expr="chromeos">
+/**
+ * @enum {string} Look at ToJSDeviceReportingType usage in
+ * management_ui_handler.cc for more details.
+ */
+export const DeviceReportingType = {
+ SUPERVISED_USER: 'supervised user',
+ DEVICE_ACTIVITY: 'device activity',
+ STATISTIC: 'device statistics',
+ DEVICE: 'device',
+ LOGS: 'logs',
+ PRINT: 'print',
+ CROSTINI: 'crostini'
+};
+
+
+/**
+ * @typedef {{
+ * messageId: string,
+ * reportingType: !DeviceReportingType,
+ * }}
+ */
+export let DeviceReportingResponse;
+// </if>
+
+/** @interface */
+export class ManagementBrowserProxy {
+ /** @return {!Promise<!Array<!Extension>>} */
+ getExtensions() {}
+ // <if expr="chromeos">
/**
- * @typedef {{
- * messageId: string,
- * reportingType: !management.ReportingType,
- * }}
+ * @return {!Promise<boolean>} Boolean describing trust root configured
+ * or not.
*/
- let BrowserReportingResponse;
+ getLocalTrustRootsInfo() {}
/**
- * @typedef {{
- * browserManagementNotice: string,
- * extensionReportingTitle: string,
- * pageSubtitle: string,
- * managed: boolean,
- * overview: string,
- * customerLogo: string,
- * threatProtectionDescription: string
- * }}
+ * @return {!Promise<!Array<DeviceReportingResponse>>} List of
+ * items to display in device reporting section.
*/
- let ManagedDataResponse;
+ getDeviceReportingInfo() {}
+ // </if>
- /**
- * @typedef {{
- * title: string,
- * permission: string
- * }}
- */
- let ThreatProtectionPermission;
+ /** @return {!Promise<!ManagedDataResponse>} */
+ getContextualManagedData() {}
- /**
- * @typedef {{
- * info: !Array<!ThreatProtectionPermission>,
- * description: string
- * }}
- */
- let ThreatProtectionInfo;
+ /** @return {!Promise<!ThreatProtectionInfo>} */
+ getThreatProtectionInfo() {}
- // <if expr="chromeos">
/**
- * @enum {string} Look at ToJSDeviceReportingType usage in
- * management_ui_handler.cc for more details.
+ * @return {!Promise<!Array<!BrowserReportingResponse>>} The list
+ * of browser reporting info messages.
*/
- const DeviceReportingType = {
- SUPERVISED_USER: 'supervised user',
- DEVICE_ACTIVITY: 'device activity',
- STATISTIC: 'device statistics',
- DEVICE: 'device',
- LOGS: 'logs',
- PRINT: 'print',
- CROSTINI: 'crostini'
- };
+ initBrowserReportingInfo() {}
+}
+
+/** @implements {ManagementBrowserProxy} */
+export class ManagementBrowserProxyImpl {
+ /** @override */
+ getExtensions() {
+ return sendWithPromise('getExtensions');
+ }
+ // <if expr="chromeos">
+ /** @override */
+ getLocalTrustRootsInfo() {
+ return sendWithPromise('getLocalTrustRootsInfo');
+ }
- /**
- * @typedef {{
- * messageId: string,
- * reportingType: !management.DeviceReportingType,
- * }}
- */
- let DeviceReportingResponse;
+ /** @override */
+ getDeviceReportingInfo() {
+ return sendWithPromise('getDeviceReportingInfo');
+ }
// </if>
- /** @interface */
- class ManagementBrowserProxy {
- /** @return {!Promise<!Array<!management.Extension>>} */
- getExtensions() {}
-
- // <if expr="chromeos">
- /**
- * @return {!Promise<boolean>} Boolean describing trust root configured
- * or not.
- */
- getLocalTrustRootsInfo() {}
-
- /**
- * @return {!Promise<!Array<management.DeviceReportingResponse>>} List of
- * items to display in device reporting section.
- */
- getDeviceReportingInfo() {}
- // </if>
-
- /** @return {!Promise<!management.ManagedDataResponse>} */
- getContextualManagedData() {}
-
- /** @return {!Promise<!management.ThreatProtectionInfo>} */
- getThreatProtectionInfo() {}
-
- /**
- * @return {!Promise<!Array<!management.BrowserReportingResponse>>} The list
- * of browser reporting info messages.
- */
- initBrowserReportingInfo() {}
+ /** @override */
+ getContextualManagedData() {
+ return sendWithPromise('getContextualManagedData');
+ }
+
+ /** @override */
+ getThreatProtectionInfo() {
+ return sendWithPromise('getThreatProtectionInfo');
}
- /** @implements {management.ManagementBrowserProxy} */
- class ManagementBrowserProxyImpl {
- /** @override */
- getExtensions() {
- return cr.sendWithPromise('getExtensions');
- }
-
- // <if expr="chromeos">
- /** @override */
- getLocalTrustRootsInfo() {
- return cr.sendWithPromise('getLocalTrustRootsInfo');
- }
-
- /** @override */
- getDeviceReportingInfo() {
- return cr.sendWithPromise('getDeviceReportingInfo');
- }
- // </if>
-
- /** @override */
- getContextualManagedData() {
- return cr.sendWithPromise('getContextualManagedData');
- }
-
- /** @override */
- getThreatProtectionInfo() {
- return cr.sendWithPromise('getThreatProtectionInfo');
- }
-
- /** @override */
- initBrowserReportingInfo() {
- return cr.sendWithPromise('initBrowserReportingInfo');
- }
+ /** @override */
+ initBrowserReportingInfo() {
+ return sendWithPromise('initBrowserReportingInfo');
}
+}
+
+addSingletonGetter(ManagementBrowserProxyImpl);
- cr.addSingletonGetter(ManagementBrowserProxyImpl);
-
- return {
- BrowserReportingResponse: BrowserReportingResponse,
- // <if expr="chromeos">
- DeviceReportingResponse: DeviceReportingResponse,
- DeviceReportingType: DeviceReportingType,
- // </if>
- Extension: Extension,
- ManagedDataResponse: ManagedDataResponse,
- ManagementBrowserProxyImpl: ManagementBrowserProxyImpl,
- ManagementBrowserProxy: ManagementBrowserProxy,
- ReportingType: ReportingType,
- ThreatProtectionInfo: ThreatProtectionInfo,
- };
-});
+// Export |ManagementBrowserProxyImpl| on |window| so that it can be accessed by
+// management_ui_browsertest.cc
+window.ManagementBrowserProxyImpl = ManagementBrowserProxyImpl;
diff --git a/chromium/chrome/browser/resources/management/management_ui.html b/chromium/chrome/browser/resources/management/management_ui.html
index f52326d1ad8..93ecc899507 100644
--- a/chromium/chrome/browser/resources/management/management_ui.html
+++ b/chromium/chrome/browser/resources/management/management_ui.html
@@ -1,20 +1,4 @@
-<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/cr_icons_css.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_page_host_style_css.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">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/load_time_data.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="icons.html">
-<link rel="import" href="management_browser_proxy.html">
-
-<dom-module id="management-ui">
- <template>
<style include="cr-icons cr-hidden-style cr-page-host-style
cr-shared-style">
:host {
@@ -324,6 +308,3 @@
</div>
</div>
</main>
- </template>
- <script src="management_ui.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/management/management_ui.js b/chromium/chrome/browser/resources/management/management_ui.js
index a04d5ed4935..4968ac9d058 100644
--- a/chromium/chrome/browser/resources/management/management_ui.js
+++ b/chromium/chrome/browser/resources/management/management_ui.js
@@ -2,294 +2,309 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('management', function() {
- /**
- * @typedef {{
- * messageIds: !Array<string>,
- * icon: string,
- * }}
- */
- let BrowserReportingData;
-
- Polymer({
- is: 'management-ui',
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icons_css.m.js';
+import 'chrome://resources/cr_elements/cr_page_host_style_css.m.js';
+import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.m.js';
+import 'chrome://resources/cr_elements/hidden_style_css.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/shared_style_css.m.js';
+import './icons.js';
+import './strings.m.js';
+
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {BrowserReportingResponse, Extension, ManagementBrowserProxy, ManagementBrowserProxyImpl, ReportingType, ThreatProtectionInfo} from './management_browser_proxy.js';
+// <if expr="chromeos">
+import {DeviceReportingResponse, DeviceReportingType} from './management_browser_proxy.js';
+// </if>
+
+/**
+ * @typedef {{
+ * messageIds: !Array<string>,
+ * icon: string,
+ * }}
+ */
+let BrowserReportingData;
+
+Polymer({
+ is: 'management-ui',
+
+ _template: html`{__html_template__}`,
+
+ behaviors: [
+ I18nBehavior,
+ WebUIListenerBehavior,
+ ],
+
+ properties: {
+ /**
+ * List of messages related to browser reporting.
+ * @private {?Array<!BrowserReportingData>}
+ */
+ browserReportingInfo_: Array,
- behaviors: [
- I18nBehavior,
- WebUIListenerBehavior,
- ],
+ /**
+ * List of messages related to browser reporting.
+ * @private {?Array<!Extension>}
+ */
+ extensions_: Array,
- properties: {
- /**
- * List of messages related to browser reporting.
- * @private {?Array<!management.BrowserReportingData>}
- */
- browserReportingInfo_: Array,
+ // <if expr="chromeos">
+ /**
+ * List of messages related to device reporting.
+ * @private {?Array<!DeviceReportingResponse>}
+ */
+ deviceReportingInfo_: Array,
- /**
- * List of messages related to browser reporting.
- * @private {?Array<!management.Extension>}
- */
- extensions_: Array,
+ /**
+ * Message stating if the Trust Roots are configured.
+ * @private
+ */
+ localTrustRoots_: String,
- // <if expr="chromeos">
- /**
- * List of messages related to device reporting.
- * @private {?Array<!management.DeviceReportingResponse>}
- */
- deviceReportingInfo_: Array,
+ /** @private */
+ customerLogo_: String,
- /**
- * Message stating if the Trust Roots are configured.
- * @private
- */
- localTrustRoots_: String,
+ /** @private */
+ managementOverview_: String,
- /** @private */
- customerLogo_: String,
+ // </if>
- /** @private */
- managementOverview_: String,
+ /** @private */
+ subtitle_: String,
- // </if>
+ // <if expr="not chromeos">
+ /** @private */
+ managementNoticeHtml_: String,
+ // </if>
- /** @private */
- subtitle_: String,
+ /** @private */
+ managed_: Boolean,
- // <if expr="not chromeos">
- /** @private */
- managementNoticeHtml_: String,
- // </if>
+ /** @private */
+ extensionReportingSubtitle_: String,
- /** @private */
- managed_: Boolean,
+ /** @private {!ThreatProtectionInfo} */
+ threatProtectionInfo_: Object,
+ },
- /** @private */
- extensionReportingSubtitle_: String,
+ /** @private {?ManagementBrowserProxy} */
+ browserProxy_: null,
- /** @private {!management.ThreatProtectionInfo} */
- threatProtectionInfo_: Object,
- },
+ /** @override */
+ attached() {
+ document.documentElement.classList.remove('loading');
+ this.browserProxy_ = ManagementBrowserProxyImpl.getInstance();
+ this.updateManagedFields_();
+ this.initBrowserReportingInfo_();
+ this.getThreatProtectionInfo_();
- /** @private {?management.ManagementBrowserProxy} */
- browserProxy_: null,
+ this.addWebUIListener(
+ 'browser-reporting-info-updated',
+ reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo));
- /** @override */
- attached() {
- document.documentElement.classList.remove('loading');
- this.browserProxy_ = management.ManagementBrowserProxyImpl.getInstance();
+ this.addWebUIListener('managed_data_changed', () => {
this.updateManagedFields_();
- this.initBrowserReportingInfo_();
- this.getThreatProtectionInfo_();
-
- this.addWebUIListener(
- 'browser-reporting-info-updated',
- reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo));
-
- this.addWebUIListener('managed_data_changed', () => {
- this.updateManagedFields_();
- });
-
- this.addWebUIListener(
- 'threat-protection-info-updated',
- info => this.threatProtectionInfo_ = info);
-
- this.getExtensions_();
- // <if expr="chromeos">
- this.getDeviceReportingInfo_();
- this.getLocalTrustRootsInfo_();
- // </if>
- },
-
- /** @private */
- initBrowserReportingInfo_() {
- this.browserProxy_.initBrowserReportingInfo().then(
- reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo));
- },
+ });
- /**
- * @param {!Array<!management.BrowserReportingResponse>} reportingInfo
- * @private
- */
- onBrowserReportingInfoReceived_(reportingInfo) {
- const reportingInfoMap = reportingInfo.reduce((info, response) => {
- info[response.reportingType] = info[response.reportingType] || {
- icon: this.getIconForReportingType_(response.reportingType),
- messageIds: []
- };
- info[response.reportingType].messageIds.push(response.messageId);
- return info;
- }, {});
-
- const reportingTypeOrder = {
- [management.ReportingType.SECURITY]: 1,
- [management.ReportingType.EXTENSIONS]: 2,
- [management.ReportingType.USER]: 3,
- [management.ReportingType.USER_ACTIVITY]: 4,
- [management.ReportingType.DEVICE]: 5,
- };
-
- this.browserReportingInfo_ =
- Object.keys(reportingInfoMap)
- .sort((a, b) => reportingTypeOrder[a] - reportingTypeOrder[b])
- .map(reportingType => reportingInfoMap[reportingType]);
- },
-
- /** @private */
- getExtensions_() {
- this.browserProxy_.getExtensions().then(extensions => {
- this.extensions_ = extensions;
- });
- },
-
- /** @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;
- },
+ this.addWebUIListener(
+ 'threat-protection-info-updated',
+ info => this.threatProtectionInfo_ = info);
+ this.getExtensions_();
// <if expr="chromeos">
- /** @private */
- getLocalTrustRootsInfo_() {
- this.browserProxy_.getLocalTrustRootsInfo().then(trustRootsConfigured => {
- this.localTrustRoots_ = trustRootsConfigured ?
- loadTimeData.getString('managementTrustRootsConfigured') :
- '';
- });
- },
+ this.getDeviceReportingInfo_();
+ this.getLocalTrustRootsInfo_();
+ // </if>
+ },
- /** @private */
- getDeviceReportingInfo_() {
- this.browserProxy_.getDeviceReportingInfo().then(reportingInfo => {
- this.deviceReportingInfo_ = reportingInfo;
- });
- },
+ /** @private */
+ initBrowserReportingInfo_() {
+ this.browserProxy_.initBrowserReportingInfo().then(
+ reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo));
+ },
- /**
- * @return {boolean} True of there are device reporting info to show.
- * @private
- */
- showDeviceReportingInfo_() {
- return !!this.deviceReportingInfo_ &&
- this.deviceReportingInfo_.length > 0;
- },
+ /**
+ * @param {!Array<!BrowserReportingResponse>} reportingInfo
+ * @private
+ */
+ onBrowserReportingInfoReceived_(reportingInfo) {
+ const reportingInfoMap = reportingInfo.reduce((info, response) => {
+ info[response.reportingType] = info[response.reportingType] || {
+ icon: this.getIconForReportingType_(response.reportingType),
+ messageIds: []
+ };
+ info[response.reportingType].messageIds.push(response.messageId);
+ return info;
+ }, {});
+
+ const reportingTypeOrder = {
+ [ReportingType.SECURITY]: 1,
+ [ReportingType.EXTENSIONS]: 2,
+ [ReportingType.USER]: 3,
+ [ReportingType.USER_ACTIVITY]: 4,
+ [ReportingType.DEVICE]: 5,
+ };
+
+ this.browserReportingInfo_ =
+ Object.keys(reportingInfoMap)
+ .sort((a, b) => reportingTypeOrder[a] - reportingTypeOrder[b])
+ .map(reportingType => reportingInfoMap[reportingType]);
+ },
+
+ /** @private */
+ getExtensions_() {
+ this.browserProxy_.getExtensions().then(extensions => {
+ this.extensions_ = extensions;
+ });
+ },
+
+ /** @private */
+ getThreatProtectionInfo_() {
+ this.browserProxy_.getThreatProtectionInfo().then(info => {
+ this.threatProtectionInfo_ = info;
+ });
+ },
- /**
- * @param {management.DeviceReportingType} reportingType
- * @return {string} The associated icon.
- * @private
- */
- getIconForDeviceReportingType_(reportingType) {
- switch (reportingType) {
- case management.DeviceReportingType.SUPERVISED_USER:
- return 'management:supervised-user';
- case management.DeviceReportingType.DEVICE_ACTIVITY:
- return 'management:timelapse';
- case management.DeviceReportingType.STATISTIC:
- return 'management:bar-chart';
- case management.DeviceReportingType.DEVICE:
- return 'cr:computer';
- case management.DeviceReportingType.LOGS:
- return 'management:report';
- case management.DeviceReportingType.PRINT:
- return 'cr:print';
- case management.DeviceReportingType.CROSTINI:
- return 'management:linux';
- default:
- return 'cr:computer';
- }
- },
- // </if>
+ /**
+ * @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_() {
+ this.browserProxy_.getLocalTrustRootsInfo().then(trustRootsConfigured => {
+ this.localTrustRoots_ = trustRootsConfigured ?
+ loadTimeData.getString('managementTrustRootsConfigured') :
+ '';
+ });
+ },
+
+ /** @private */
+ getDeviceReportingInfo_() {
+ this.browserProxy_.getDeviceReportingInfo().then(reportingInfo => {
+ this.deviceReportingInfo_ = reportingInfo;
+ });
+ },
- /**
- * @return {boolean} True of there are browser reporting info to show.
- * @private
- */
- showBrowserReportingInfo_() {
- return !!this.browserReportingInfo_ &&
- this.browserReportingInfo_.length > 0;
- },
+ /**
+ * @return {boolean} True of there are device reporting info to show.
+ * @private
+ */
+ showDeviceReportingInfo_() {
+ return !!this.deviceReportingInfo_ && this.deviceReportingInfo_.length > 0;
+ },
- /**
- * @return {boolean} True of there are extension reporting info to show.
- * @private
- */
- showExtensionReportingInfo_() {
- return !!this.extensions_ && this.extensions_.length > 0;
- },
+ /**
+ * @param {DeviceReportingType} reportingType
+ * @return {string} The associated icon.
+ * @private
+ */
+ getIconForDeviceReportingType_(reportingType) {
+ switch (reportingType) {
+ case DeviceReportingType.SUPERVISED_USER:
+ return 'management:supervised-user';
+ case DeviceReportingType.DEVICE_ACTIVITY:
+ return 'management:timelapse';
+ case DeviceReportingType.STATISTIC:
+ return 'management:bar-chart';
+ case DeviceReportingType.DEVICE:
+ return 'cr:computer';
+ case DeviceReportingType.LOGS:
+ return 'management:report';
+ case DeviceReportingType.PRINT:
+ return 'cr:print';
+ case DeviceReportingType.CROSTINI:
+ return 'management:linux';
+ default:
+ return 'cr:computer';
+ }
+ },
+ // </if>
- /**
- * @param {management.ReportingType} reportingType
- * @returns {string} The associated icon.
- * @private
- */
- getIconForReportingType_(reportingType) {
- switch (reportingType) {
- case management.ReportingType.SECURITY:
- return 'cr:security';
- case management.ReportingType.DEVICE:
- return 'cr:computer';
- case management.ReportingType.EXTENSIONS:
- return 'cr:extension';
- case management.ReportingType.USER:
- return 'management:account-circle';
- case management.ReportingType.USER_ACTIVITY:
- return 'management:public';
- default:
- return 'cr:security';
- }
- },
+ /**
+ * @return {boolean} True of there are browser reporting info to show.
+ * @private
+ */
+ showBrowserReportingInfo_() {
+ return !!this.browserReportingInfo_ &&
+ this.browserReportingInfo_.length > 0;
+ },
- /**
- * Handles the 'search-changed' event fired from the toolbar.
- * Redirects to the settings page initialized the the current
- * search query.
- * @param {!CustomEvent<string>} e
- * @private
- */
- onSearchChanged_: function(e) {
- const query = e.detail;
- window.location.href =
- `chrome://settings?search=${encodeURIComponent(query)}`;
- },
+ /**
+ * @return {boolean} True of there are extension reporting info to show.
+ * @private
+ */
+ showExtensionReportingInfo_() {
+ return !!this.extensions_ && this.extensions_.length > 0;
+ },
- /** @private */
- onTapBack_() {
- if (history.length > 1) {
- history.back();
- } else {
- window.location.href = 'chrome://settings/help';
- }
- },
+ /**
+ * @param {ReportingType} reportingType
+ * @returns {string} The associated icon.
+ * @private
+ */
+ getIconForReportingType_(reportingType) {
+ switch (reportingType) {
+ case ReportingType.SECURITY:
+ return 'cr:security';
+ case ReportingType.DEVICE:
+ return 'cr:computer';
+ case ReportingType.EXTENSIONS:
+ return 'cr:extension';
+ case ReportingType.USER:
+ return 'management:account-circle';
+ case ReportingType.USER_ACTIVITY:
+ return 'management:public';
+ default:
+ return 'cr:security';
+ }
+ },
- /** @private */
- updateManagedFields_() {
- this.browserProxy_.getContextualManagedData().then(data => {
- this.managed_ = data.managed;
- this.extensionReportingSubtitle_ = data.extensionReportingTitle;
- this.subtitle_ = data.pageSubtitle;
- // <if expr="chromeos">
- this.customerLogo_ = data.customerLogo;
- this.managementOverview_ = data.overview;
- // </if>
- // <if expr="not chromeos">
- this.managementNoticeHtml_ = data.browserManagementNotice;
- // </if>
- });
- },
- });
-
- return {
- BrowserReportingData: BrowserReportingData,
- };
+ /**
+ * Handles the 'search-changed' event fired from the toolbar.
+ * Redirects to the settings page initialized the the current
+ * search query.
+ * @param {!CustomEvent<string>} e
+ * @private
+ */
+ onSearchChanged_: function(e) {
+ const query = e.detail;
+ window.location.href =
+ `chrome://settings?search=${encodeURIComponent(query)}`;
+ },
+
+ /** @private */
+ onTapBack_() {
+ if (history.length > 1) {
+ history.back();
+ } else {
+ window.location.href = 'chrome://settings/help';
+ }
+ },
+
+ /** @private */
+ updateManagedFields_() {
+ this.browserProxy_.getContextualManagedData().then(data => {
+ this.managed_ = data.managed;
+ this.extensionReportingSubtitle_ = data.extensionReportingTitle;
+ this.subtitle_ = data.pageSubtitle;
+ // <if expr="chromeos">
+ this.customerLogo_ = data.customerLogo;
+ this.managementOverview_ = data.overview;
+ // </if>
+ // <if expr="not chromeos">
+ this.managementNoticeHtml_ = data.browserManagementNotice;
+ // </if>
+ });
+ },
});
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn b/chromium/chrome/browser/resources/media_router/BUILD.gn
index 7a2ca5ce91a..6afd405a48e 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/BUILD.gn
+++ b/chromium/chrome/browser/resources/media_router/BUILD.gn
@@ -6,10 +6,13 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
- ":viewer-toolbar-dropdown",
+ ":media_router_internals",
]
}
-js_library("viewer-toolbar-dropdown") {
- deps = []
+js_library("media_router_internals") {
+ deps = [
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:util.m",
+ ]
}
diff --git a/chromium/chrome/browser/resources/media_router/media_router_internals.html b/chromium/chrome/browser/resources/media_router/media_router_internals.html
index 09e1b94867f..751c30eae0d 100644
--- a/chromium/chrome/browser/resources/media_router/media_router_internals.html
+++ b/chromium/chrome/browser/resources/media_router/media_router_internals.html
@@ -3,9 +3,7 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="media_router_internals.css">
- <link rel="import" href="chrome://resources/html/cr.html">
- <link rel="import" href="chrome://resources/html/util.html">
- <script src="media_router_internals.js"></script>
+ <script type="module" src="media_router_internals.js"></script>
</head>
<body>
<div id="sink-status-div"></div>
diff --git a/chromium/chrome/browser/resources/media_router/media_router_internals.js b/chromium/chrome/browser/resources/media_router/media_router_internals.js
index 7f801e26ad8..28e32f80548 100644
--- a/chromium/chrome/browser/resources/media_router/media_router_internals.js
+++ b/chromium/chrome/browser/resources/media_router/media_router_internals.js
@@ -2,29 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Handles user events for the Media Router Internals UI.
-cr.define('media_router_internals', function() {
- 'use strict';
-
- /**
- * Initializes the Media Router Internals WebUI
- */
- function initialize() {
- // Notify the browser that the page has loaded, causing it to send media
- // router status.
- chrome.send('initialized');
- }
+import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {$} from 'chrome://resources/js/util.m.js';
- function setStatus(status) {
+// Handles user events for the Media Router Internals UI.
+document.addEventListener('DOMContentLoaded', function() {
+ sendWithPromise('getStatus').then(status => {
const jsonStatus = JSON.stringify(status, null, /* spacing level = */ 2);
$('sink-status-div').textContent = jsonStatus;
- }
-
- return {
- initialize: initialize,
- setStatus: setStatus,
- };
+ });
});
-
-document.addEventListener(
- 'DOMContentLoaded', media_router_internals.initialize);
diff --git a/chromium/chrome/browser/resources/ntp4/apps_page.js b/chromium/chrome/browser/resources/ntp4/apps_page.js
index 026b45813c5..460883b526e 100644
--- a/chromium/chrome/browser/resources/ntp4/apps_page.js
+++ b/chromium/chrome/browser/resources/ntp4/apps_page.js
@@ -105,7 +105,7 @@ cr.define('ntp', function() {
*/
appendMenuItem_: function(opt_textId) {
const button =
- /** @type {!HTMLButtonElement} */ (cr.doc.createElement('button'));
+ /** @type {!HTMLButtonElement} */ (document.createElement('button'));
this.menu.appendChild(button);
cr.ui.decorate(button, cr.ui.MenuItem);
if (opt_textId) {
@@ -248,7 +248,7 @@ cr.define('ntp', function() {
* @extends {HTMLDivElement}
*/
function App(appData) {
- const el = cr.doc.createElement('div');
+ const el = /** @type {!App} */ (document.createElement('div'));
el.__proto__ = App.prototype;
el.initialize(appData);
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css b/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
index 1e2b3cc2b3c..95c06095f56 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -11,7 +11,7 @@ body {
@media (prefers-color-scheme: dark) {
html {
- background: rgb(50, 54, 57);
+ background: rgb(53, 54, 58);
color: rgb(232, 234, 237); /* --google-grey-200 */
}
}
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.css b/chromium/chrome/browser/resources/ntp4/incognito_tab.css
index c2beff126d3..a5f3cbb6931 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.css
@@ -8,12 +8,16 @@ body {
margin: 0;
}
+[hidden] {
+ display: none !important;
+}
+
/** Typography -------------------------------------------------------------- */
.content {
/* This is identical to the default background color. It's necessary to set it
for the case when a theme with a background image is installed. */
- background-color: rgb(50, 54, 57);
+ background-color: rgb(53, 54, 58);
color: rgb(232, 234, 237); /* --google-grey-200 */
font-size: calc(100% - 2px);
line-height: calc(100% + 6px);
@@ -96,6 +100,34 @@ em {
}
}
+/** Cookie Controls --------------------------------------------------------- */
+
+#cookie-controls {
+ align-items: center;
+ background-color: rgb(60, 64, 67); /* --google-grey-800 */
+ border-radius: 4px;
+ box-sizing: border-box;
+ display: flex;
+ padding: 12px 20px;
+}
+
+#cookie-controls-description {
+ flex: 1;
+ padding-inline-end: 20px;
+}
+
+#cookie-controls-description em {
+ display: block;
+}
+
+#cookie-controls-toggle {
+ flex: none;
+}
+
+#cookie-controls-toggle:not(:defined) {
+ width: 34px;
+}
+
/** Layout ------------------------------------------------------------------ */
/* Align the content, icon, and title to to the center. */
@@ -167,7 +199,8 @@ h1 {
.icon,
h1,
#subtitle,
- .bulletpoints {
+ .bulletpoints,
+ #cookie-controls {
margin-bottom: 1.5rem;
}
@@ -209,7 +242,8 @@ h1 {
.learn-more-button,
.bulletpoints,
- .icon {
+ .icon,
+ #cookie-controls {
margin-bottom: 16px;
}
}
@@ -230,7 +264,8 @@ h1 {
}
.bulletpoints,
- .learn-more-button {
+ .learn-more-button,
+ #cookie-controls {
margin-bottom: 1.5rem;
}
@@ -248,7 +283,8 @@ h1 {
}
.bulletpoints,
- .learn-more-button {
+ .learn-more-button,
+ #cookie-controls {
margin-bottom: 1rem;
}
}
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.html b/chromium/chrome/browser/resources/ntp4/incognito_tab.html
index 888489f7ccb..48631cb04f8 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_tab.html
+++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.html
@@ -30,10 +30,21 @@ document.write('<link id="incognitothemecss" rel="stylesheet" ' +
<div class="bulletpoints first">$i18nRaw{incognitoTabFeatures}</div>
<div class="bulletpoints">$i18nRaw{incognitoTabWarning}</div>
</div>
+ <div id="cookie-controls" $i18n{hideCookieControls}>
+ <div id="cookie-controls-description">
+ <em>$i18n{cookieControlsTitle}</em>
+ $i18n{cookieControlsDescription}
+ </div>
+ <cr-toggle id="cookie-controls-toggle"
+ aria-label="$i18n{cookieControlsTitle}"
+ $i18n{cookieControlsToggleChecked} dark></cr-toggle>
+ </div>
<a class="learn-more-button" href="$i18n{learnMoreLink}">$i18n{learnMore}</a>
</div>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="incognito_tab.js"></script>
+<!-- Lazy-load cr_toggle to avoid performance penalty introduced by loading Polymer -->
+<script type="module" src="chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js" async></script>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/ntp4/incognito_tab.js b/chromium/chrome/browser/resources/ntp4/incognito_tab.js
index bca80d57e69..aa7de31ab36 100644
--- a/chromium/chrome/browser/resources/ntp4/incognito_tab.js
+++ b/chromium/chrome/browser/resources/ntp4/incognito_tab.js
@@ -3,7 +3,25 @@
// found in the LICENSE file.
window.addEventListener('load', function() {
+ cr.addWebUIListener('theme-changed', themeData => {
+ document.documentElement.setAttribute(
+ 'hascustombackground', themeData.hasCustomBackground);
+ $('incognitothemecss').href =
+ 'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now();
+ });
chrome.send('observeThemeChanges');
+
+ cr.addWebUIListener('cookie-controls-changed', checked => {
+ $('cookie-controls-toggle').checked = checked;
+ });
+ cr.addWebUIListener(
+ 'third-party-cookie-blocking-changed', shouldHideCookieControls => {
+ $('cookie-controls').hidden = shouldHideCookieControls;
+ });
+ $('cookie-controls-toggle').addEventListener('change', event => {
+ chrome.send('cookieControlsToggleChanged', [event.detail]);
+ });
+ chrome.send('observeCookieControlsSettingsChanges');
});
// Handle the bookmark bar, theme, and font size change requests
@@ -13,12 +31,4 @@ const ntp = {
setBookmarkBarAttached: function(attached) {
document.documentElement.setAttribute('bookmarkbarattached', attached);
},
-
- /** @param {!{hasCustomBackground: boolean}} themeData */
- themeChanged: function(themeData) {
- document.documentElement.setAttribute(
- 'hascustombackground', themeData.hasCustomBackground);
- $('incognitothemecss').href =
- 'chrome://theme/css/incognito_new_tab_theme.css?' + Date.now();
- },
};
diff --git a/chromium/chrome/browser/resources/ntp4/nav_dot.js b/chromium/chrome/browser/resources/ntp4/nav_dot.js
index 22109133114..8193fe15190 100644
--- a/chromium/chrome/browser/resources/ntp4/nav_dot.js
+++ b/chromium/chrome/browser/resources/ntp4/nav_dot.js
@@ -22,7 +22,7 @@ cr.define('ntp', function() {
* @implements {cr.ui.DragWrapperDelegate}
*/
function NavDot(page, title, titleIsEditable, animate) {
- const dot = cr.doc.createElement('li');
+ const dot = /** @type {!NavDot} */ (document.createElement('li'));
dot.__proto__ = NavDot.prototype;
dot.initialize(page, title, titleIsEditable, animate);
diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.css b/chromium/chrome/browser/resources/ntp4/new_tab.css
index 132872957df..eba46bcfe5f 100644
--- a/chromium/chrome/browser/resources/ntp4/new_tab.css
+++ b/chromium/chrome/browser/resources/ntp4/new_tab.css
@@ -95,10 +95,9 @@ html[dir='rtl'] #attribution {
}
#footer {
- background-image: linear-gradient(
- rgba(242, 242, 242, 0.9), rgba(222, 222, 222, 0.9));
+ background-color: white;
bottom: 0;
- color: #7F7F7F;
+ color: #666;
font-size: 0.9em;
font-weight: bold;
overflow: hidden;
@@ -273,7 +272,7 @@ html[dir='rtl'] #footer.showing-trash-mode #trash.drag-target .lid {
#chrome-web-store-link {
-webkit-order: 3;
- color: inherit;
+ color: rgb(26, 115, 232);
cursor: pointer;
display: inline-block;
margin: 0;
@@ -291,10 +290,6 @@ html[dir='rtl'] #footer.showing-trash-mode #trash.drag-target .lid {
padding-inline-start: 15px;
}
-#chrome-web-store-link:hover {
- color: #666;
-}
-
html[dir='rtl'] #chrome-web-store-title {
background-position-x: left;
}
diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.html b/chromium/chrome/browser/resources/ntp4/new_tab.html
index de19cad2443..2b60f4a75a6 100644
--- a/chromium/chrome/browser/resources/ntp4/new_tab.html
+++ b/chromium/chrome/browser/resources/ntp4/new_tab.html
@@ -80,7 +80,7 @@ document.write('<link id="themecss" rel="stylesheet" ' +
<div id="footer-border"></div>
<div id="footer-content">
<div id="logo-img">
- <img alt="" src="chrome://theme/IDR_PRODUCT_LOGO">
+ <img alt="" src="chrome://theme/IDR_PRODUCT_LOGO_32">
</div>
<ul id="dot-list">
diff --git a/chromium/chrome/browser/resources/ntp4/new_tab.js b/chromium/chrome/browser/resources/ntp4/new_tab.js
index 0be7cd9f7a7..d6f7b960b48 100644
--- a/chromium/chrome/browser/resources/ntp4/new_tab.js
+++ b/chromium/chrome/browser/resources/ntp4/new_tab.js
@@ -108,6 +108,10 @@ cr.define('ntp', function() {
startTime = Date.now();
+ cr.addWebUIListener('theme-changed', () => {
+ $('themecss').href =
+ 'chrome://theme/css/new_tab_theme.css?' + Date.now();
+ });
chrome.send('observeThemeChanges');
});
}
@@ -207,15 +211,6 @@ cr.define('ntp', function() {
}
}
- /**
- * Called when the theme has changed.
- * @param {Object=} opt_themeData Not used; only exists to match equivalent
- * function in incognito NTP.
- */
- function themeChanged(opt_themeData) {
- $('themecss').href = 'chrome://theme/css/new_tab_theme.css?' + Date.now();
- }
-
function setBookmarkBarAttached(attached) {
document.documentElement.setAttribute('bookmarkbarattached', attached);
}
@@ -390,7 +385,6 @@ cr.define('ntp', function() {
setAppToBeHighlighted: setAppToBeHighlighted,
setBookmarkBarAttached: setBookmarkBarAttached,
setFaviconDominantColor: setFaviconDominantColor,
- themeChanged: themeChanged,
updateLogin: updateLogin
};
});
diff --git a/chromium/chrome/browser/resources/ntp4/tile_page.js b/chromium/chrome/browser/resources/ntp4/tile_page.js
index f6de15ab41c..600fc1f09b4 100644
--- a/chromium/chrome/browser/resources/ntp4/tile_page.js
+++ b/chromium/chrome/browser/resources/ntp4/tile_page.js
@@ -41,7 +41,7 @@ cr.define('ntp', function() {
* @extends {HTMLDivElement}
*/
function Tile(contents) {
- const tile = cr.doc.createElement('div');
+ const tile = /** @type {!Tile} */ (document.createElement('div'));
tile.__proto__ = Tile.prototype;
tile.initialize(contents);
@@ -372,7 +372,7 @@ cr.define('ntp', function() {
* @implements {cr.ui.DragWrapperDelegate}
*/
function TilePage(gridValues) {
- const el = cr.doc.createElement('div');
+ const el = /** @type {!TilePage} */ (document.createElement('div'));
el.gridValues_ = gridValues;
el.__proto__ = TilePage.prototype;
el.initialize();
diff --git a/chromium/chrome/browser/resources/offline_pages/BUILD.gn b/chromium/chrome/browser/resources/offline_pages/BUILD.gn
index 83c60714a90..fe9c078c3a3 100644
--- a/chromium/chrome/browser/resources/offline_pages/BUILD.gn
+++ b/chromium/chrome/browser/resources/offline_pages/BUILD.gn
@@ -14,15 +14,13 @@ js_type_check("closure_compile") {
js_library("offline_internals") {
deps = [
":offline_internals_browser_proxy",
- "//ui/webui/resources/js:assert",
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:util.m",
]
}
js_library("offline_internals_browser_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
}
diff --git a/chromium/chrome/browser/resources/offline_pages/offline_internals.html b/chromium/chrome/browser/resources/offline_pages/offline_internals.html
index d00c5decc19..95383662692 100644
--- a/chromium/chrome/browser/resources/offline_pages/offline_internals.html
+++ b/chromium/chrome/browser/resources/offline_pages/offline_internals.html
@@ -7,12 +7,7 @@
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="offline_internals.css">
- <link rel="import" href="chrome://resources/html/cr.html">
- <script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://resources/js/util.js"></script>
- <script src="strings.js"></script>
- <script src="offline_internals_browser_proxy.js"></script>
- <script src="offline_internals.js"></script>
+ <script type="module" src="offline_internals.js"></script>
</head>
<body>
<h1>Offline Internals</h1>
diff --git a/chromium/chrome/browser/resources/offline_pages/offline_internals.js b/chromium/chrome/browser/resources/offline_pages/offline_internals.js
index a5ffaa3c6c2..fa4ddffd6aa 100644
--- a/chromium/chrome/browser/resources/offline_pages/offline_internals.js
+++ b/chromium/chrome/browser/resources/offline_pages/offline_internals.js
@@ -2,362 +2,359 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('offlineInternals', function() {
- 'use strict';
-
- /** @type {!Array<OfflinePage>} */
- let offlinePages = [];
-
- /** @type {!Array<SavePageRequest>} */
- let savePageRequests = [];
-
- /** @type {!offlineInternals.OfflineInternalsBrowserProxy} */
- const browserProxy =
- offlineInternals.OfflineInternalsBrowserProxyImpl.getInstance();
-
- /**
- * Fill stored pages table.
- * @param {!Array<OfflinePage>} pages An array object representing
- * stored offline pages.
- */
- function fillStoredPages(pages) {
- const storedPagesTable = $('stored-pages');
- storedPagesTable.textContent = '';
-
- const template = $('stored-pages-table-row');
- const td = template.content.querySelectorAll('td');
- for (let pageIndex = 0; pageIndex < pages.length; pageIndex++) {
- const page = pages[pageIndex];
- td[0].textContent = pageIndex + 1;
- const checkbox = td[1].querySelector('input');
- checkbox.setAttribute('value', page.id);
-
- const link = td[2].querySelector('a');
- link.setAttribute('href', page.onlineUrl);
- const maxUrlCharsPerLine = 50;
- if (page.onlineUrl.length > maxUrlCharsPerLine) {
- link.textContent = '';
- for (let i = 0; i < page.onlineUrl.length; i += maxUrlCharsPerLine) {
- link.textContent += page.onlineUrl.slice(i, i + maxUrlCharsPerLine);
- link.textContent += '\r\n';
- }
- } else {
- link.textContent = page.onlineUrl;
+import './strings.m.js';
+
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {$} from 'chrome://resources/js/util.m.js';
+
+import {IsLogging, OfflineInternalsBrowserProxy, OfflineInternalsBrowserProxyImpl, OfflinePage, SavePageRequest} from './offline_internals_browser_proxy.js';
+
+/** @type {!Array<OfflinePage>} */
+let offlinePages = [];
+
+/** @type {!Array<SavePageRequest>} */
+let savePageRequests = [];
+
+/** @type {!OfflineInternalsBrowserProxy} */
+const browserProxy = OfflineInternalsBrowserProxyImpl.getInstance();
+
+/**
+ * Fill stored pages table.
+ * @param {!Array<OfflinePage>} pages An array object representing
+ * stored offline pages.
+ */
+function fillStoredPages(pages) {
+ const storedPagesTable = $('stored-pages');
+ storedPagesTable.textContent = '';
+
+ const template = $('stored-pages-table-row');
+ const td = template.content.querySelectorAll('td');
+ for (let pageIndex = 0; pageIndex < pages.length; pageIndex++) {
+ const page = pages[pageIndex];
+ td[0].textContent = pageIndex + 1;
+ const checkbox = td[1].querySelector('input');
+ checkbox.setAttribute('value', page.id);
+
+ const link = td[2].querySelector('a');
+ link.setAttribute('href', page.onlineUrl);
+ const maxUrlCharsPerLine = 50;
+ if (page.onlineUrl.length > maxUrlCharsPerLine) {
+ link.textContent = '';
+ for (let i = 0; i < page.onlineUrl.length; i += maxUrlCharsPerLine) {
+ link.textContent += page.onlineUrl.slice(i, i + maxUrlCharsPerLine);
+ link.textContent += '\r\n';
}
-
- td[3].textContent = page.namespace;
- td[4].textContent = Math.round(page.size / 1024);
-
- const row = document.importNode(template.content, true);
- storedPagesTable.appendChild(row);
- }
- offlinePages = pages;
- }
-
- /**
- * Fill requests table.
- * @param {!Array<SavePageRequest>} requests An array object representing
- * the request queue.
- */
- function fillRequestQueue(requests) {
- const requestQueueTable = $('request-queue');
- requestQueueTable.textContent = '';
-
- const template = $('request-queue-table-row');
- const td = template.content.querySelectorAll('td');
- for (const request of requests) {
- const checkbox = td[0].querySelector('input');
- checkbox.setAttribute('value', request.id);
-
- td[1].textContent = request.onlineUrl;
- td[2].textContent = new Date(request.creationTime);
- td[3].textContent = request.status;
- td[4].textContent = request.requestOrigin;
-
- const row = document.importNode(template.content, true);
- requestQueueTable.appendChild(row);
- }
- savePageRequests = requests;
- }
-
- /**
- * Fills the event logs section.
- * @param {!Array<string>} logs A list of log strings.
- */
- function fillEventLog(logs) {
- const element = $('logs');
- element.textContent = '';
- for (const log of logs) {
- const logItem = document.createElement('li');
- logItem.textContent = log;
- element.appendChild(logItem);
+ } else {
+ link.textContent = page.onlineUrl;
}
- }
- /**
- * Refresh all displayed information.
- */
- function refreshAll() {
- browserProxy.getStoredPages().then(fillStoredPages);
- browserProxy.getRequestQueue().then(fillRequestQueue);
- browserProxy.getNetworkStatus().then(function(networkStatus) {
- $('current-status').textContent = networkStatus;
- });
- browserProxy.getLimitlessPrefetchingEnabled().then(function(enabled) {
- $('limitless-prefetching-checkbox').checked = enabled;
- });
- browserProxy.getPrefetchTestingHeaderValue().then(function(value) {
- switch (value) {
- case 'ForceEnable':
- $('testing-header-enable').checked = true;
- break;
- case 'ForceDisable':
- $('testing-header-disable').checked = true;
- break;
- default:
- $('testing-header-default').checked = true;
- }
- });
- refreshLog();
- }
+ td[3].textContent = page.namespace;
+ td[4].textContent = Math.round(page.size / 1024);
- /**
- * Callback when pages are deleted.
- * @param {string} status The status of the request.
- */
- function pagesDeleted(status) {
- $('page-actions-info').textContent = status;
- browserProxy.getStoredPages().then(fillStoredPages);
+ const row = document.importNode(template.content, true);
+ storedPagesTable.appendChild(row);
}
-
- /**
- * Callback when requests are deleted.
- */
- function requestsDeleted(status) {
- $('request-queue-actions-info').textContent = status;
- browserProxy.getRequestQueue().then(fillRequestQueue);
+ offlinePages = pages;
+}
+
+/**
+ * Fill requests table.
+ * @param {!Array<SavePageRequest>} requests An array object representing
+ * the request queue.
+ */
+function fillRequestQueue(requests) {
+ const requestQueueTable = $('request-queue');
+ requestQueueTable.textContent = '';
+
+ const template = $('request-queue-table-row');
+ const td = template.content.querySelectorAll('td');
+ for (const request of requests) {
+ const checkbox = td[0].querySelector('input');
+ checkbox.setAttribute('value', request.id);
+
+ td[1].textContent = request.onlineUrl;
+ td[2].textContent = new Date(request.creationTime);
+ td[3].textContent = request.status;
+ td[4].textContent = request.requestOrigin;
+
+ const row = document.importNode(template.content, true);
+ requestQueueTable.appendChild(row);
}
-
- /**
- * Callback for prefetch actions.
- * @param {string} info The result of performing the prefetch actions.
- */
- function setPrefetchResult(info) {
- $('prefetch-actions-info').textContent = info;
+ savePageRequests = requests;
+}
+
+/**
+ * Fills the event logs section.
+ * @param {!Array<string>} logs A list of log strings.
+ */
+function fillEventLog(logs) {
+ const element = $('logs');
+ element.textContent = '';
+ for (const log of logs) {
+ const logItem = document.createElement('li');
+ logItem.textContent = log;
+ element.appendChild(logItem);
}
-
- /**
- * Error callback for prefetch actions.
- * @param {*} error The error that resulted from the prefetch call.
- */
- function prefetchResultError(error) {
- const errorText = error && error.message ? error.message : error;
-
- $('prefetch-actions-info').textContent = 'Error: ' + errorText;
- }
-
- /**
- * Downloads all the stored page and request queue information into a file.
- * Also translates all the fields representing datetime into human-readable
- * date strings.
- * TODO(chili): Create a CSV writer that can abstract out the line joining.
- */
- function dumpAsJson() {
- const json = JSON.stringify(
- {offlinePages: offlinePages, savePageRequests: savePageRequests},
- function(key, value) {
- return key.endsWith('Time') ? new Date(value).toString() : value;
- },
- 2);
-
- $('dump-box').value = json;
- $('dump-info').textContent = '';
- $('dump-modal').showModal();
- $('dump-box').select();
- }
-
- function closeDump() {
- $('dump-modal').close();
- $('dump-box').value = '';
- }
-
- function copyDump() {
- $('dump-box').select();
- document.execCommand('copy');
- $('dump-info').textContent = 'Copied to clipboard!';
- }
-
- /**
- * Updates the status strings.
- * @param {!IsLogging} logStatus Status of logging.
- */
- function updateLogStatus(logStatus) {
- $('model-checkbox').checked = logStatus.modelIsLogging;
- $('request-checkbox').checked = logStatus.queueIsLogging;
- $('prefetch-checkbox').checked = logStatus.prefetchIsLogging;
- }
-
- /**
- * Sets all checkboxes with a specific name to the same checked status as the
- * provided source checkbox.
- * @param {HTMLElement} source The checkbox controlling the checked
- * status.
- * @param {string} checkboxesName The name identifying the checkboxes to set.
- */
- function toggleAllCheckboxes(source, checkboxesName) {
- const checkboxes = document.getElementsByName(checkboxesName);
- for (const checkbox of checkboxes) {
- checkbox.checked = source.checked;
+}
+
+/**
+ * Refresh all displayed information.
+ */
+function refreshAll() {
+ browserProxy.getStoredPages().then(fillStoredPages);
+ browserProxy.getRequestQueue().then(fillRequestQueue);
+ browserProxy.getNetworkStatus().then(function(networkStatus) {
+ $('current-status').textContent = networkStatus;
+ });
+ browserProxy.getLimitlessPrefetchingEnabled().then(function(enabled) {
+ $('limitless-prefetching-checkbox').checked = enabled;
+ });
+ browserProxy.getPrefetchTestingHeaderValue().then(function(value) {
+ switch (value) {
+ case 'ForceEnable':
+ $('testing-header-enable').checked = true;
+ break;
+ case 'ForceDisable':
+ $('testing-header-disable').checked = true;
+ break;
+ default:
+ $('testing-header-default').checked = true;
}
+ });
+ refreshLog();
+}
+
+/**
+ * Callback when pages are deleted.
+ * @param {string} status The status of the request.
+ */
+function pagesDeleted(status) {
+ $('page-actions-info').textContent = status;
+ browserProxy.getStoredPages().then(fillStoredPages);
+}
+
+/**
+ * Callback when requests are deleted.
+ */
+function requestsDeleted(status) {
+ $('request-queue-actions-info').textContent = status;
+ browserProxy.getRequestQueue().then(fillRequestQueue);
+}
+
+/**
+ * Callback for prefetch actions.
+ * @param {string} info The result of performing the prefetch actions.
+ */
+function setPrefetchResult(info) {
+ $('prefetch-actions-info').textContent = info;
+}
+
+/**
+ * Error callback for prefetch actions.
+ * @param {*} error The error that resulted from the prefetch call.
+ */
+function prefetchResultError(error) {
+ const errorText = error && error.message ? error.message : error;
+
+ $('prefetch-actions-info').textContent = 'Error: ' + errorText;
+}
+
+/**
+ * Downloads all the stored page and request queue information into a file.
+ * Also translates all the fields representing datetime into human-readable
+ * date strings.
+ * TODO(chili): Create a CSV writer that can abstract out the line joining.
+ */
+function dumpAsJson() {
+ const json = JSON.stringify(
+ {offlinePages: offlinePages, savePageRequests: savePageRequests},
+ function(key, value) {
+ return key.endsWith('Time') ? new Date(value).toString() : value;
+ },
+ 2);
+
+ $('dump-box').value = json;
+ $('dump-info').textContent = '';
+ $('dump-modal').showModal();
+ $('dump-box').select();
+}
+
+function closeDump() {
+ $('dump-modal').close();
+ $('dump-box').value = '';
+}
+
+function copyDump() {
+ $('dump-box').select();
+ document.execCommand('copy');
+ $('dump-info').textContent = 'Copied to clipboard!';
+}
+
+/**
+ * Updates the status strings.
+ * @param {!IsLogging} logStatus Status of logging.
+ */
+function updateLogStatus(logStatus) {
+ $('model-checkbox').checked = logStatus.modelIsLogging;
+ $('request-checkbox').checked = logStatus.queueIsLogging;
+ $('prefetch-checkbox').checked = logStatus.prefetchIsLogging;
+}
+
+/**
+ * Sets all checkboxes with a specific name to the same checked status as the
+ * provided source checkbox.
+ * @param {HTMLElement} source The checkbox controlling the checked
+ * status.
+ * @param {string} checkboxesName The name identifying the checkboxes to set.
+ */
+function toggleAllCheckboxes(source, checkboxesName) {
+ const checkboxes = document.getElementsByName(checkboxesName);
+ for (const checkbox of checkboxes) {
+ checkbox.checked = source.checked;
}
-
- /**
- * Return the item ids for the selected checkboxes with a given name.
- * @param {string} checkboxesName The name identifying the checkboxes to
- * query.
- * @return {!Array<string>} An array of selected ids.
- */
- function getSelectedIdsFor(checkboxesName) {
- const checkboxes = document.querySelectorAll(
- `input[type="checkbox"][name="${checkboxesName}"]:checked`);
- return Array.from(checkboxes).map(c => c.value);
- }
-
- /**
- * Refreshes the logs.
- */
- function refreshLog() {
- browserProxy.getEventLogs().then(fillEventLog);
- browserProxy.getLoggingState().then(updateLogStatus);
- }
-
- /**
- * Calls scheduleNwake and indicates how long the scheduled delay will be.
- */
- function ensureBackgroundTaskScheduledWithDelay() {
- browserProxy.scheduleNwake()
- .then((result) => {
- // The delays in these messages should correspond to the scheduling
- // delays defined in PrefetchBackgroundTaskScheduler.java.
- if ($('limitless-prefetching-checkbox').checked) {
- setPrefetchResult(
- result +
- ' (Limitless mode enabled; background task scheduled to run' +
- ' in a few seconds.)');
- } else {
- setPrefetchResult(
- result +
- ' (Limitless mode disabled; background task scheduled to run' +
- ' in several minutes.)');
+}
+
+/**
+ * Return the item ids for the selected checkboxes with a given name.
+ * @param {string} checkboxesName The name identifying the checkboxes to
+ * query.
+ * @return {!Array<string>} An array of selected ids.
+ */
+function getSelectedIdsFor(checkboxesName) {
+ const checkboxes = document.querySelectorAll(
+ `input[type="checkbox"][name="${checkboxesName}"]:checked`);
+ return Array.from(checkboxes).map(c => c.value);
+}
+
+/**
+ * Refreshes the logs.
+ */
+function refreshLog() {
+ browserProxy.getEventLogs().then(fillEventLog);
+ browserProxy.getLoggingState().then(updateLogStatus);
+}
+
+/**
+ * Calls scheduleNwake and indicates how long the scheduled delay will be.
+ */
+function ensureBackgroundTaskScheduledWithDelay() {
+ browserProxy.scheduleNwake()
+ .then((result) => {
+ // The delays in these messages should correspond to the scheduling
+ // delays defined in PrefetchBackgroundTaskScheduler.java.
+ if ($('limitless-prefetching-checkbox').checked) {
+ setPrefetchResult(
+ result +
+ ' (Limitless mode enabled; background task scheduled to run' +
+ ' in a few seconds.)');
+ } else {
+ setPrefetchResult(
+ result +
+ ' (Limitless mode disabled; background task scheduled to run' +
+ ' in several minutes.)');
+ }
+ })
+ .catch(prefetchResultError);
+}
+
+function initialize() {
+ const incognito = loadTimeData.getBoolean('isIncognito');
+ ['delete-selected-pages', 'delete-selected-requests', 'model-checkbox',
+ 'request-checkbox', 'refresh']
+ .forEach(el => $(el).disabled = incognito);
+
+ $('delete-selected-pages').onclick = function() {
+ const pageIds = getSelectedIdsFor('stored');
+ browserProxy.deleteSelectedPages(pageIds).then(pagesDeleted);
+ };
+ $('delete-selected-requests').onclick = function() {
+ const requestIds = getSelectedIdsFor('requests');
+ browserProxy.deleteSelectedRequests(requestIds).then(requestsDeleted);
+ };
+ $('refresh').onclick = refreshAll;
+ $('dump').onclick = dumpAsJson;
+ $('close-dump').onclick = closeDump;
+ $('copy-to-clipboard').onclick = copyDump;
+ $('model-checkbox').onchange = (evt) => {
+ browserProxy.setRecordPageModel(evt.target.checked);
+ };
+ $('request-checkbox').onchange = (evt) => {
+ browserProxy.setRecordRequestQueue(evt.target.checked);
+ };
+ $('prefetch-checkbox').onchange = (evt) => {
+ browserProxy.setRecordPrefetchService(evt.target.checked);
+ };
+ $('refresh-logs').onclick = refreshLog;
+ $('add-to-queue').onclick = function() {
+ const saveUrls = $('url').value.split(',');
+ let counter = saveUrls.length;
+ $('save-url-state').textContent = '';
+ for (let i = 0; i < saveUrls.length; i++) {
+ browserProxy.addToRequestQueue(saveUrls[i]).then(function(state) {
+ if (state) {
+ $('save-url-state').textContent +=
+ saveUrls[i] + ' has been added to queue.\n';
+ $('url').value = '';
+ counter--;
+ if (counter == 0) {
+ browserProxy.getRequestQueue().then(fillRequestQueue);
}
- })
+ } else {
+ $('save-url-state').textContent +=
+ saveUrls[i] + ' failed to be added to queue.\n';
+ }
+ });
+ }
+ };
+ $('schedule-nwake').onclick = function() {
+ browserProxy.scheduleNwake()
+ .then(setPrefetchResult)
.catch(prefetchResultError);
- }
-
- function initialize() {
- const incognito = loadTimeData.getBoolean('isIncognito');
- ['delete-selected-pages', 'delete-selected-requests', 'model-checkbox',
- 'request-checkbox', 'refresh']
- .forEach(el => $(el).disabled = incognito);
-
- $('delete-selected-pages').onclick = function() {
- const pageIds = getSelectedIdsFor('stored');
- browserProxy.deleteSelectedPages(pageIds).then(pagesDeleted);
- };
- $('delete-selected-requests').onclick = function() {
- const requestIds = getSelectedIdsFor('requests');
- browserProxy.deleteSelectedRequests(requestIds).then(requestsDeleted);
- };
- $('refresh').onclick = refreshAll;
- $('dump').onclick = dumpAsJson;
- $('close-dump').onclick = closeDump;
- $('copy-to-clipboard').onclick = copyDump;
- $('model-checkbox').onchange = (evt) => {
- browserProxy.setRecordPageModel(evt.target.checked);
- };
- $('request-checkbox').onchange = (evt) => {
- browserProxy.setRecordRequestQueue(evt.target.checked);
- };
- $('prefetch-checkbox').onchange = (evt) => {
- browserProxy.setRecordPrefetchService(evt.target.checked);
- };
- $('refresh-logs').onclick = refreshLog;
- $('add-to-queue').onclick = function() {
- const saveUrls = $('url').value.split(',');
- let counter = saveUrls.length;
- $('save-url-state').textContent = '';
- for (let i = 0; i < saveUrls.length; i++) {
- browserProxy.addToRequestQueue(saveUrls[i]).then(function(state) {
- if (state) {
- $('save-url-state').textContent +=
- saveUrls[i] + ' has been added to queue.\n';
- $('url').value = '';
- counter--;
- if (counter == 0) {
- browserProxy.getRequestQueue().then(fillRequestQueue);
- }
- } else {
- $('save-url-state').textContent +=
- saveUrls[i] + ' failed to be added to queue.\n';
- }
- });
- }
- };
- $('schedule-nwake').onclick = function() {
- browserProxy.scheduleNwake()
- .then(setPrefetchResult)
- .catch(prefetchResultError);
- };
- $('cancel-nwake').onclick = function() {
- browserProxy.cancelNwake()
- .then(setPrefetchResult)
- .catch(prefetchResultError);
- };
- $('show-notification').onclick = function() {
- browserProxy.showPrefetchNotification().then(setPrefetchResult);
- };
- $('generate-page-bundle').onclick = function() {
- browserProxy.generatePageBundle($('generate-urls').value)
- .then(setPrefetchResult)
- .catch(prefetchResultError);
- };
- $('get-operation').onclick = function() {
- browserProxy.getOperation($('operation-name').value)
- .then(setPrefetchResult)
- .catch(prefetchResultError);
- };
- $('download-archive').onclick = function() {
- browserProxy.downloadArchive($('download-name').value);
- };
- $('toggle-all-stored').onclick = function() {
- toggleAllCheckboxes($('toggle-all-stored'), 'stored');
- };
- $('toggle-all-requests').onclick = function() {
- toggleAllCheckboxes($('toggle-all-requests'), 'requests');
- };
- $('limitless-prefetching-checkbox').onchange = (evt) => {
- browserProxy.setLimitlessPrefetchingEnabled(evt.target.checked);
- if (evt.target.checked) {
- ensureBackgroundTaskScheduledWithDelay();
- }
- };
- // Helper for setting prefetch testing header from a radio button.
- const setPrefetchTestingHeader = function(evt) {
- browserProxy.setPrefetchTestingHeaderValue(evt.target.value);
+ };
+ $('cancel-nwake').onclick = function() {
+ browserProxy.cancelNwake()
+ .then(setPrefetchResult)
+ .catch(prefetchResultError);
+ };
+ $('show-notification').onclick = function() {
+ browserProxy.showPrefetchNotification().then(setPrefetchResult);
+ };
+ $('generate-page-bundle').onclick = function() {
+ browserProxy.generatePageBundle($('generate-urls').value)
+ .then(setPrefetchResult)
+ .catch(prefetchResultError);
+ };
+ $('get-operation').onclick = function() {
+ browserProxy.getOperation($('operation-name').value)
+ .then(setPrefetchResult)
+ .catch(prefetchResultError);
+ };
+ $('download-archive').onclick = function() {
+ browserProxy.downloadArchive($('download-name').value);
+ };
+ $('toggle-all-stored').onclick = function() {
+ toggleAllCheckboxes($('toggle-all-stored'), 'stored');
+ };
+ $('toggle-all-requests').onclick = function() {
+ toggleAllCheckboxes($('toggle-all-requests'), 'requests');
+ };
+ $('limitless-prefetching-checkbox').onchange = (evt) => {
+ browserProxy.setLimitlessPrefetchingEnabled(evt.target.checked);
+ if (evt.target.checked) {
ensureBackgroundTaskScheduledWithDelay();
- };
- $('testing-header-default').onchange = setPrefetchTestingHeader;
- $('testing-header-enable').onchange = setPrefetchTestingHeader;
- $('testing-header-disable').onchange = setPrefetchTestingHeader;
- if (!incognito) {
- refreshAll();
}
- }
-
- // Return an object with all of the exports.
- return {
- initialize: initialize,
};
-});
+ // Helper for setting prefetch testing header from a radio button.
+ const setPrefetchTestingHeader = function(evt) {
+ browserProxy.setPrefetchTestingHeaderValue(evt.target.value);
+ ensureBackgroundTaskScheduledWithDelay();
+ };
+ $('testing-header-default').onchange = setPrefetchTestingHeader;
+ $('testing-header-enable').onchange = setPrefetchTestingHeader;
+ $('testing-header-disable').onchange = setPrefetchTestingHeader;
+ if (!incognito) {
+ refreshAll();
+ }
+}
-document.addEventListener('DOMContentLoaded', offlineInternals.initialize);
+document.addEventListener('DOMContentLoaded', initialize);
diff --git a/chromium/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js b/chromium/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js
index f9da3c8548b..d72e9235d6e 100644
--- a/chromium/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js
+++ b/chromium/chrome/browser/resources/offline_pages/offline_internals_browser_proxy.js
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+
/**
* @typedef {{
* onlineUrl: string,
@@ -16,7 +18,7 @@
* requestOrigin: string
* }}
*/
-let OfflinePage;
+export let OfflinePage;
/**
* @typedef {{
@@ -29,7 +31,7 @@ let OfflinePage;
* requestOrigin: string
* }}
*/
-let SavePageRequest;
+export let SavePageRequest;
/**
* @typedef {{
@@ -38,275 +40,262 @@ let SavePageRequest;
* prefetchIsLogging: boolean
* }}
*/
-let IsLogging;
-
-cr.define('offlineInternals', function() {
- /** @interface */
- function OfflineInternalsBrowserProxy() {}
-
- OfflineInternalsBrowserProxy.prototype = {
- /**
- * Gets current list of stored pages.
- * @return {!Promise<!Array<OfflinePage>>} A promise firing when the
- * list is fetched.
- */
- getStoredPages: function() {},
-
- /**
- * Gets current offline queue requests.
- * @return {!Promise<!Array<SavePageRequest>>} A promise firing when the
- * request queue is fetched.
- */
- getRequestQueue: function() {},
-
- /**
- * Deletes a set of pages from stored pages
- * @param {!Array<string>} ids A list of page IDs to delete.
- * @return {!Promise<!string>} A promise firing when the selected
- * pages are deleted.
- */
- deleteSelectedPages: function(ids) {},
-
- /**
- * Deletes a set of requests from the request queue
- * @param {!Array<string>} ids A list of request IDs to delete.
- * @return {!Promise<!string>} A promise firing when the selected
- * pages are deleted.
- */
- deleteSelectedRequests: function(ids) {},
-
- /**
- * Sets whether to record logs for stored pages.
- * @param {boolean} shouldLog True if logging should be enabled.
- */
- setRecordPageModel: function(shouldLog) {},
-
- /**
- * Sets whether to record logs for scheduled requests.
- * @param {boolean} shouldLog True if logging should be enabled.
- */
- setRecordRequestQueue: function(shouldLog) {},
-
- /**
- * Sets whether to record logs for prefetching.
- * @param {boolean} shouldLog True if logging should be enabled.
- */
- setRecordPrefetchService: function(shouldLog) {},
-
- /**
- * Sets whether limitless prefetching is enabled.
- * @param {boolean} enabled Whether to enable limitless prefetching.
- */
- setLimitlessPrefetchingEnabled: function(enabled) {},
-
- /**
- * Gets whether limitless prefetching is enabled.
- * @return {!Promise<boolean>} Whether limitless prefetching is enabled
- */
- getLimitlessPrefetchingEnabled: function() {},
-
- /**
- * Sets the value to be sent with the prefetch testing header for
- * GeneratePageBundle requests.
- * @param {string} value Value to send with X-Offline-Prefetch-Testing.
- */
- setPrefetchTestingHeaderValue: function(value) {},
-
- /**
- * Gets the value of the prefetch testing header to be sent with
- * GeneratePageBundle requests.
- * @return {!Promise<string>} Header value.
- */
- getPrefetchTestingHeaderValue: function() {},
-
- /**
- * Gets the currently recorded logs.
- * @return {!Promise<!Array<string>>} A promise firing when the
- * logs are retrieved.
- */
- getEventLogs: function() {},
-
- /**
- * Gets the state of logging (on/off).
- * @return {!Promise<!IsLogging>} A promise firing when the state
- * is retrieved.
- */
- getLoggingState: function() {},
-
- /**
- * Adds the given url to the background loader queue.
- * @param {string} url Url of the page to load later.
- * @return {!Promise<boolean>} A promise firing after added to queue.
- * Promise will return true if url has been successfully added.
- */
- addToRequestQueue: function(url) {},
-
- /**
- * Gets the current network status in string form.
- * @return {!Promise<string>} A promise firing when the network status
- * is retrieved.
- */
- getNetworkStatus: function() {},
-
- /**
- * Schedules the default NWake task. The returned Promise will reject if
- * there is an error while scheduling.
- * @return {!Promise<string>} A promise firing when the task has been
- * scheduled.
- */
- scheduleNwake: function() {},
-
- /**
- * Cancels NWake task.
- * @return {!Promise} A promise firing when the task has been cancelled. The
- * returned Promise will reject if there is an error.
- */
- cancelNwake: function() {},
-
- /**
- * Shows the prefetching notification with an example origin.
- * @return {!Promise<string>} A promise firing when the notification has
- * been shown.
- */
- showPrefetchNotification: function() {},
-
- /**
- * Sends and processes a request to generate page bundle.
- * @param {string} urls A list of comma-separated URLs.
- * @return {!Promise<string>} A string describing the result.
- */
- generatePageBundle: function(urls) {},
-
- /**
- * Sends and processes a request to get operation.
- * @param {string} name Name of operation.
- * @return {!Promise<string>} A string describing the result.
- */
- getOperation: function(name) {},
-
- /**
- * Downloads an archive.
- * @param {string} name Name of archive to download.
- */
- downloadArchive: function(name) {},
- };
+export let IsLogging;
+
+/** @interface */
+export class OfflineInternalsBrowserProxy {
+ /**
+ * Gets current list of stored pages.
+ * @return {!Promise<!Array<OfflinePage>>} A promise firing when the
+ * list is fetched.
+ */
+ getStoredPages() {}
+
+ /**
+ * Gets current offline queue requests.
+ * @return {!Promise<!Array<SavePageRequest>>} A promise firing when the
+ * request queue is fetched.
+ */
+ getRequestQueue() {}
+
+ /**
+ * Deletes a set of pages from stored pages
+ * @param {!Array<string>} ids A list of page IDs to delete.
+ * @return {!Promise<!string>} A promise firing when the selected
+ * pages are deleted.
+ */
+ deleteSelectedPages(ids) {}
+
+ /**
+ * Deletes a set of requests from the request queue
+ * @param {!Array<string>} ids A list of request IDs to delete.
+ * @return {!Promise<!string>} A promise firing when the selected
+ * pages are deleted.
+ */
+ deleteSelectedRequests(ids) {}
+
+ /**
+ * Sets whether to record logs for stored pages.
+ * @param {boolean} shouldLog True if logging should be enabled.
+ */
+ setRecordPageModel(shouldLog) {}
+
+ /**
+ * Sets whether to record logs for scheduled requests.
+ * @param {boolean} shouldLog True if logging should be enabled.
+ */
+ setRecordRequestQueue(shouldLog) {}
+
+ /**
+ * Sets whether to record logs for prefetching.
+ * @param {boolean} shouldLog True if logging should be enabled.
+ */
+ setRecordPrefetchService(shouldLog) {}
+
+ /**
+ * Sets whether limitless prefetching is enabled.
+ * @param {boolean} enabled Whether to enable limitless prefetching.
+ */
+ setLimitlessPrefetchingEnabled(enabled) {}
+
+ /**
+ * Gets whether limitless prefetching is enabled.
+ * @return {!Promise<boolean>} Whether limitless prefetching is enabled
+ */
+ getLimitlessPrefetchingEnabled() {}
+
+ /**
+ * Sets the value to be sent with the prefetch testing header for
+ * GeneratePageBundle requests.
+ * @param {string} value Value to send with X-Offline-Prefetch-Testing.
+ */
+ setPrefetchTestingHeaderValue(value) {}
+
+ /**
+ * Gets the value of the prefetch testing header to be sent with
+ * GeneratePageBundle requests.
+ * @return {!Promise<string>} Header value.
+ */
+ getPrefetchTestingHeaderValue() {}
+
+ /**
+ * Gets the currently recorded logs.
+ * @return {!Promise<!Array<string>>} A promise firing when the
+ * logs are retrieved.
+ */
+ getEventLogs() {}
+
+ /**
+ * Gets the state of logging (on/off).
+ * @return {!Promise<!IsLogging>} A promise firing when the state
+ * is retrieved.
+ */
+ getLoggingState() {}
+
+ /**
+ * Adds the given url to the background loader queue.
+ * @param {string} url Url of the page to load later.
+ * @return {!Promise<boolean>} A promise firing after added to queue.
+ * Promise will return true if url has been successfully added.
+ */
+ addToRequestQueue(url) {}
+
+ /**
+ * Gets the current network status in string form.
+ * @return {!Promise<string>} A promise firing when the network status
+ * is retrieved.
+ */
+ getNetworkStatus() {}
+
+ /**
+ * Schedules the default NWake task. The returned Promise will reject if
+ * there is an error while scheduling.
+ * @return {!Promise<string>} A promise firing when the task has been
+ * scheduled.
+ */
+ scheduleNwake() {}
+
+ /**
+ * Cancels NWake task.
+ * @return {!Promise} A promise firing when the task has been cancelled. The
+ * returned Promise will reject if there is an error.
+ */
+ cancelNwake() {}
+
+ /**
+ * Shows the prefetching notification with an example origin.
+ * @return {!Promise<string>} A promise firing when the notification has
+ * been shown.
+ */
+ showPrefetchNotification() {}
+
+ /**
+ * Sends and processes a request to generate page bundle.
+ * @param {string} urls A list of comma-separated URLs.
+ * @return {!Promise<string>} A string describing the result.
+ */
+ generatePageBundle(urls) {}
+
+ /**
+ * Sends and processes a request to get operation.
+ * @param {string} name Name of operation.
+ * @return {!Promise<string>} A string describing the result.
+ */
+ getOperation(name) {}
/**
- * @constructor
- * @implements {offlineInternals.OfflineInternalsBrowserProxy}
+ * Downloads an archive.
+ * @param {string} name Name of archive to download.
*/
- function OfflineInternalsBrowserProxyImpl() {}
- cr.addSingletonGetter(OfflineInternalsBrowserProxyImpl);
-
- OfflineInternalsBrowserProxyImpl.prototype = {
- /** @override */
- getStoredPages: function() {
- return cr.sendWithPromise('getStoredPages');
- },
-
- /** @override */
- getRequestQueue: function() {
- return cr.sendWithPromise('getRequestQueue');
- },
-
- /** @override */
- deleteSelectedPages: function(ids) {
- return cr.sendWithPromise('deleteSelectedPages', ids);
- },
-
- /** @override */
- deleteSelectedRequests: function(ids) {
- return cr.sendWithPromise('deleteSelectedRequests', ids);
- },
-
- /** @override */
- setRecordPageModel: function(shouldLog) {
- chrome.send('setRecordPageModel', [shouldLog]);
- },
-
- /** @override */
- setRecordRequestQueue: function(shouldLog) {
- chrome.send('setRecordRequestQueue', [shouldLog]);
- },
-
- /** @override */
- setRecordPrefetchService: function(shouldLog) {
- chrome.send('setRecordPrefetchService', [shouldLog]);
- },
-
- /** @override */
- setLimitlessPrefetchingEnabled: function(enabled) {
- chrome.send('setLimitlessPrefetchingEnabled', [enabled]);
- },
-
- /** @override */
- getLimitlessPrefetchingEnabled: function() {
- return cr.sendWithPromise('getLimitlessPrefetchingEnabled');
- },
-
- /** @override */
- setPrefetchTestingHeaderValue: function(value) {
- chrome.send('setPrefetchTestingHeader', [value]);
- },
-
- /** @override */
- getPrefetchTestingHeaderValue: function() {
- return cr.sendWithPromise('getPrefetchTestingHeader');
- },
-
- /** @override */
- getEventLogs: function() {
- return cr.sendWithPromise('getEventLogs');
- },
-
- /** @override */
- getLoggingState: function() {
- return cr.sendWithPromise('getLoggingState');
- },
-
- /** @override */
- addToRequestQueue: function(url) {
- return cr.sendWithPromise('addToRequestQueue', url);
- },
-
- /** @override */
- getNetworkStatus: function() {
- return cr.sendWithPromise('getNetworkStatus');
- },
-
- /** @override */
- scheduleNwake: function() {
- return cr.sendWithPromise('scheduleNwake');
- },
-
- /** @override */
- cancelNwake: function() {
- return cr.sendWithPromise('cancelNwake');
- },
-
- /** @override */
- showPrefetchNotification: function() {
- return cr.sendWithPromise('showPrefetchNotification');
- },
-
- /** @override */
- generatePageBundle: function(urls) {
- return cr.sendWithPromise('generatePageBundle', urls);
- },
-
- /** @override */
- getOperation: function(name) {
- return cr.sendWithPromise('getOperation', name);
- },
-
- /** @override */
- downloadArchive: function(name) {
- chrome.send('downloadArchive', [name]);
- },
- };
-
- return {
- OfflineInternalsBrowserProxy: OfflineInternalsBrowserProxy,
- OfflineInternalsBrowserProxyImpl: OfflineInternalsBrowserProxyImpl
- };
-});
+ downloadArchive(name) {}
+}
+
+/** @implements {OfflineInternalsBrowserProxy} */
+export class OfflineInternalsBrowserProxyImpl {
+ /** @override */
+ getStoredPages() {
+ return sendWithPromise('getStoredPages');
+ }
+
+ /** @override */
+ getRequestQueue() {
+ return sendWithPromise('getRequestQueue');
+ }
+
+ /** @override */
+ deleteSelectedPages(ids) {
+ return sendWithPromise('deleteSelectedPages', ids);
+ }
+
+ /** @override */
+ deleteSelectedRequests(ids) {
+ return sendWithPromise('deleteSelectedRequests', ids);
+ }
+
+ /** @override */
+ setRecordPageModel(shouldLog) {
+ chrome.send('setRecordPageModel', [shouldLog]);
+ }
+
+ /** @override */
+ setRecordRequestQueue(shouldLog) {
+ chrome.send('setRecordRequestQueue', [shouldLog]);
+ }
+
+ /** @override */
+ setRecordPrefetchService(shouldLog) {
+ chrome.send('setRecordPrefetchService', [shouldLog]);
+ }
+
+ /** @override */
+ setLimitlessPrefetchingEnabled(enabled) {
+ chrome.send('setLimitlessPrefetchingEnabled', [enabled]);
+ }
+
+ /** @override */
+ getLimitlessPrefetchingEnabled() {
+ return sendWithPromise('getLimitlessPrefetchingEnabled');
+ }
+
+ /** @override */
+ setPrefetchTestingHeaderValue(value) {
+ chrome.send('setPrefetchTestingHeader', [value]);
+ }
+
+ /** @override */
+ getPrefetchTestingHeaderValue() {
+ return sendWithPromise('getPrefetchTestingHeader');
+ }
+
+ /** @override */
+ getEventLogs() {
+ return sendWithPromise('getEventLogs');
+ }
+
+ /** @override */
+ getLoggingState() {
+ return sendWithPromise('getLoggingState');
+ }
+
+ /** @override */
+ addToRequestQueue(url) {
+ return sendWithPromise('addToRequestQueue', url);
+ }
+
+ /** @override */
+ getNetworkStatus() {
+ return sendWithPromise('getNetworkStatus');
+ }
+
+ /** @override */
+ scheduleNwake() {
+ return sendWithPromise('scheduleNwake');
+ }
+
+ /** @override */
+ cancelNwake() {
+ return sendWithPromise('cancelNwake');
+ }
+
+ /** @override */
+ showPrefetchNotification() {
+ return sendWithPromise('showPrefetchNotification');
+ }
+
+ /** @override */
+ generatePageBundle(urls) {
+ return sendWithPromise('generatePageBundle', urls);
+ }
+
+ /** @override */
+ getOperation(name) {
+ return sendWithPromise('getOperation', name);
+ }
+
+ /** @override */
+ downloadArchive(name) {
+ chrome.send('downloadArchive', [name]);
+ }
+}
+
+addSingletonGetter(OfflineInternalsBrowserProxyImpl);
diff --git a/chromium/chrome/browser/resources/omnibox/BUILD.gn b/chromium/chrome/browser/resources/omnibox/BUILD.gn
index 0465f914112..c3634a0f8f1 100644
--- a/chromium/chrome/browser/resources/omnibox/BUILD.gn
+++ b/chromium/chrome/browser/resources/omnibox/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 = [
@@ -32,3 +33,23 @@ js_library("omnibox_output") {
]
externs_list = [ "$externs_path/pending.js" ]
}
+
+grit("resources") {
+ source = "resources.grd"
+
+ # The .grd contains references to generated files.
+ source_is_generated = true
+ outputs = [
+ "grit/omnibox_resources.h",
+ "omnibox_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/omnibox:mojo_bindings_js",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox.html b/chromium/chrome/browser/resources/omnibox/omnibox.html
index 402bef06eb3..d5284f5df81 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox.html
+++ b/chromium/chrome/browser/resources/omnibox/omnibox.html
@@ -268,10 +268,9 @@
<span class="label">
all providers done = <span id="done"></span>
</span>
+ <span class="label">type = <span id="type"></span></span>
<span class="label">host = <span id="host"></span></span>
- <span class="label">
- has isTypedHost = <span id="is-typed-host"></span>
- </span>
+ <span class="label">is typed host = <span id="is-typed-host"></span></span>
</template>
<omnibox-input id="omnibox-input"></omnibox-input>
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox.js b/chromium/chrome/browser/resources/omnibox/omnibox.js
index c5d0e722454..b27b8b8eb88 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox.js
+++ b/chromium/chrome/browser/resources/omnibox/omnibox.js
@@ -158,7 +158,6 @@ document.addEventListener('DOMContentLoaded', () => {
exportDelegate = new ExportDelegate(omniboxOutput, omniboxInput);
omniboxInput.addEventListener('query-inputs-changed', e => {
- omniboxOutput.updateQueryInputs(e.detail);
browserProxy.makeRequest(
e.detail.inputText, e.detail.resetAutocompleteController,
e.detail.cursorPosition, e.detail.zeroSuggest,
@@ -211,7 +210,6 @@ class ExportDelegate {
}
this.omniboxInput_.queryInputs = importData.queryInputs;
this.omniboxInput_.displayInputs = importData.displayInputs;
- this.omniboxOutput_.updateQueryInputs(importData.queryInputs);
this.omniboxOutput_.updateDisplayInputs(importData.displayInputs);
this.omniboxOutput_.setResponsesHistory(importData.responsesHistory);
return true;
diff --git a/chromium/chrome/browser/resources/omnibox/omnibox_output.js b/chromium/chrome/browser/resources/omnibox/omnibox_output.js
index 72184d02c97..53815c5ff76 100644
--- a/chromium/chrome/browser/resources/omnibox/omnibox_output.js
+++ b/chromium/chrome/browser/resources/omnibox/omnibox_output.js
@@ -8,6 +8,7 @@ cr.define('omnibox_output', function() {
* cursorPosition: number,
* time: number,
* done: boolean,
+ * type: string,
* host: string,
* isTypedHost: boolean,
* }}
@@ -31,19 +32,12 @@ cr.define('omnibox_output', function() {
this.responsesHistory = [];
/** @private {!Array<!OutputResultsGroup>} */
this.resultsGroups_ = [];
- /** @private {!QueryInputs} */
- this.queryInputs_ = /** @type {!QueryInputs} */ ({});
/** @private {!DisplayInputs} */
this.displayInputs_ = OmniboxInput.defaultDisplayInputs;
/** @private {string} */
this.filterText_ = '';
}
- /** @param {!QueryInputs} queryInputs */
- updateQueryInputs(queryInputs) {
- this.queryInputs_ = queryInputs;
- }
-
/** @param {!DisplayInputs} displayInputs */
updateDisplayInputs(displayInputs) {
this.displayInputs_ = displayInputs;
@@ -103,8 +97,7 @@ cr.define('omnibox_output', function() {
* @private @param {!mojom.OmniboxResponse} response
*/
createResultsGroup_(response) {
- const resultsGroup =
- OutputResultsGroup.create(response, this.queryInputs_.cursorPosition);
+ const resultsGroup = OutputResultsGroup.create(response);
this.resultsGroups_.push(resultsGroup);
this.$$('#contents').appendChild(resultsGroup);
@@ -190,12 +183,11 @@ cr.define('omnibox_output', function() {
class OutputResultsGroup extends OmniboxElement {
/**
* @param {!mojom.OmniboxResponse} resultsGroup
- * @param {number} cursorPosition
* @return {!OutputResultsGroup}
*/
- static create(resultsGroup, cursorPosition) {
+ static create(resultsGroup) {
const outputResultsGroup = new OutputResultsGroup();
- outputResultsGroup.setResultsGroup(resultsGroup, cursorPosition);
+ outputResultsGroup.setResultsGroup(resultsGroup);
return outputResultsGroup;
}
@@ -203,18 +195,16 @@ cr.define('omnibox_output', function() {
super('output-results-group-template');
}
- /**
- * @param {!mojom.OmniboxResponse} resultsGroup
- * @param {number} cursorPosition
- */
- setResultsGroup(resultsGroup, cursorPosition) {
+ /** @param {!mojom.OmniboxResponse} resultsGroup */
+ setResultsGroup(resultsGroup) {
/** @private {ResultsDetails} */
this.details_ = {
- cursorPosition: cursorPosition,
+ cursorPosition: resultsGroup.cursorPosition,
time: resultsGroup.timeSinceOmniboxStartedMs,
done: resultsGroup.done,
+ type: resultsGroup.type,
host: resultsGroup.host,
- isTypedHost: resultsGroup.isTypedHost
+ isTypedHost: resultsGroup.isTypedHost,
};
/** @type {!Array<!OutputHeader>} */
this.headers = COLUMNS.map(OutputHeader.create);
@@ -353,6 +343,7 @@ cr.define('omnibox_output', function() {
this.$$('#cursor-position').textContent = details.cursorPosition;
this.$$('#time').textContent = details.time;
this.$$('#done').textContent = details.done;
+ this.$$('#type').textContent = details.type;
this.$$('#host').textContent = details.host;
this.$$('#is-typed-host').textContent = details.isTypedHost;
}
diff --git a/chromium/chrome/browser/resources/omnibox/resources.grd b/chromium/chrome/browser/resources/omnibox/resources.grd
new file mode 100644
index 00000000000..d6011a893e8
--- /dev/null
+++ b/chromium/chrome/browser/resources/omnibox/resources.grd
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0"
+ current_release="1"
+ output_all_resource_defines="false">
+ <outputs>
+ <output filename="grit/omnibox_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="omnibox_resources.pak" type="data_package" />
+ </outputs>
+ <release seq="1">
+ <includes>
+ <include name="IDR_OMNIBOX_HTML"
+ file="omnibox.html"
+ flattenhtml="true"
+ allowexternalscript="true"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_CSS"
+ file="omnibox.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_INPUT_CSS"
+ file="omnibox_input.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OUTPUT_RESULTS_GROUP_CSS"
+ file="output_results_group.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_OUTPUT_COLUMN_WIDTHS_CSS"
+ file="omnibox_output_column_widths.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_ELEMENT_JS"
+ file="omnibox_element.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_INPUT_JS"
+ file="omnibox_input.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_OUTPUT_JS"
+ file="omnibox_output.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_JS"
+ file="omnibox.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_OMNIBOX_MOJO_JS"
+ file="${root_gen_dir}\chrome\browser\ui\webui\omnibox\omnibox.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ </includes>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/pdf/BUILD.gn b/chromium/chrome/browser/resources/pdf/BUILD.gn
index 89a0223ca86..079381842d8 100644
--- a/chromium/chrome/browser/resources/pdf/BUILD.gn
+++ b/chromium/chrome/browser/resources/pdf/BUILD.gn
@@ -4,28 +4,19 @@
import("//third_party/closure_compiler/compile_js.gni")
-# TODO(dpapad): Add compile targets for all files, crbug.com/721073.
group("closure_compile") {
deps = [
":pdf_resources",
- "elements/viewer-bookmark:closure_compile",
- "elements/viewer-error-screen:closure_compile",
- "elements/viewer-form-warning: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",
+ "elements:closure_compile",
]
if (is_chromeos) {
- deps += [
- "elements/viewer-ink-host:closure_compile",
- "ink:closure_compile",
- ]
+ deps += [ "ink:closure_compile" ]
}
}
+js_library("annotation_tool") {
+}
+
js_library("browser_api") {
deps = [
"//ui/webui/resources/js:assert",
@@ -86,15 +77,53 @@ js_library("navigator") {
]
}
+js_library("toolbar_manager") {
+ deps = [
+ "elements:viewer-pdf-toolbar",
+ "elements:viewer-zoom-toolbar",
+ ]
+}
+
+js_library("controller") {
+ deps = [
+ ":annotation_tool",
+ ":viewport",
+ "elements:viewer-pdf-toolbar",
+ "//ui/webui/resources/js:load_time_data",
+ "//ui/webui/resources/js/cr:event_target",
+ ]
+}
+
+js_library("pdf_viewer") {
+ deps = [
+ ":controller",
+ ":navigator",
+ ":toolbar_manager",
+ ":viewport",
+ "elements:viewer-bookmark",
+ "elements:viewer-error-screen",
+ "elements:viewer-page-indicator",
+ "elements:viewer-password-screen",
+ "elements:viewer-pdf-toolbar",
+ "elements:viewer-zoom-toolbar",
+ "//ui/webui/resources/js:event_tracker",
+ "//ui/webui/resources/js:load_time_data",
+ ]
+ externs_list = [ "$externs_path/resources_private.js" ]
+}
+
js_type_check("pdf_resources") {
deps = [
":browser_api",
+ ":controller",
":gesture_detector",
":metrics",
":navigator",
":open_pdf_params_parser",
":pdf_fitting_type",
":pdf_scripting_api",
+ ":pdf_viewer",
+ ":toolbar_manager",
":viewport",
":viewport_scroller",
":zoom_manager",
diff --git a/chromium/chrome/browser/resources/pdf/annotation_tool.js b/chromium/chrome/browser/resources/pdf/annotation_tool.js
new file mode 100644
index 00000000000..5e887b048b7
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/annotation_tool.js
@@ -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.
+
+// @fileoverview This file is not included in the build. Only used for type
+// checking purposes.
+
+/**
+ * @typedef {{
+ * tool: string,
+ * size: number,
+ * color: (string|null),
+ * }}
+ */
+let AnnotationTool;
diff --git a/chromium/chrome/browser/resources/pdf/controller.js b/chromium/chrome/browser/resources/pdf/controller.js
new file mode 100644
index 00000000000..ea790f32d0f
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/controller.js
@@ -0,0 +1,494 @@
+// 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.
+
+'use strict';
+
+/** @typedef {{ type: string }} */
+let MessageData;
+
+/**
+ * @typedef {{
+ * dataToSave: Array,
+ * token: string,
+ * fileName: string
+ * }}
+ */
+let SaveDataMessageData;
+
+/**
+ * @typedef {{
+ * type: string,
+ * to: string,
+ * cc: string,
+ * bcc: string,
+ * subject: string,
+ * body: string,
+ * }}
+ */
+let EmailMessageData;
+
+/**
+ * @typedef {{
+ * type: string,
+ * url: string,
+ * grayscale: boolean,
+ * modifiable: boolean,
+ * pageNumbers: !Array<number>
+ * }}
+ */
+let PrintPreviewParams;
+
+// Note: Redefining this type here, to work around the fact that ink externs
+// are only available on Chrome OS, so the targets that contain them cannot be
+// built on other platforms.
+// TODO (rbpotter): Break InkController into its own file that is only included
+// on Chrome OS.
+
+/**
+ * @typedef {{
+ * setAnnotationTool: function(AnnotationTool):void,
+ * viewportChanged: function():void,
+ * saveDocument: function():!Promise,
+ * undo: function():void,
+ * redo: function():void,
+ * load: function(string, !ArrayBuffer):!Promise,
+ * viewport: !Viewport,
+ * }}
+ */
+let ViewerInkHostElement;
+
+/**
+ * Creates a cryptographically secure pseudorandom 128-bit token.
+ * @return {string} The generated token as a hex string.
+ */
+function createToken() {
+ const randomBytes = new Uint8Array(16);
+ return window.crypto.getRandomValues(randomBytes)
+ .map(b => b.toString(16).padStart(2, '0'))
+ .join('');
+}
+
+/** @abstract */
+class ContentController {
+ constructor() {}
+
+ beforeZoom() {}
+
+ afterZoom() {}
+
+ viewportChanged() {}
+
+ /** @abstract */
+ rotateClockwise() {}
+
+ /** @abstract */
+ rotateCounterclockwise() {}
+
+ /** Triggers printing of the current document. */
+ print() {}
+
+ /** Undo an edit action. */
+ undo() {}
+
+ /** Redo an edit action. */
+ redo() {}
+
+ /**
+ * Requests that the current document be saved.
+ * @param {boolean} requireResult whether a response is required, otherwise
+ * the controller may save the document to disk internally.
+ * @return {Promise<{fileName: string, dataToSave: ArrayBuffer}>}
+ * @abstract
+ */
+ save(requireResult) {}
+
+ /**
+ * Loads PDF document from `data` activates UI.
+ * @param {string} fileName
+ * @param {!ArrayBuffer} data
+ * @return {Promise<void>}
+ * @abstract
+ */
+ load(fileName, data) {}
+
+ /**
+ * Unloads the current document and removes the UI.
+ * @abstract
+ */
+ unload() {}
+}
+
+/**
+ * Controller for annotation mode, on Chrome OS only. Fires the following events
+ * from its event target:
+ * has-unsaved-changes: Fired to indicate there are ink annotations that have
+ * not been saved.
+ * set-annotation-undo-state: Contains information about whether undo or redo
+ * options are available.
+ */
+class InkController extends ContentController {
+ /** @param {!Viewport} viewport */
+ constructor(viewport) {
+ super();
+
+ /** @private {!Viewport} */
+ this.viewport_ = viewport;
+
+ /** @private {?ViewerInkHostElement} */
+ this.inkHost_ = null;
+
+ /** @private {!EventTarget} */
+ this.eventTarget_ = new cr.EventTarget();
+
+ /** @type {?AnnotationTool} */
+ this.tool_ = null;
+ }
+
+ /** @return {!EventTarget} */
+ getEventTarget() {
+ return this.eventTarget_;
+ }
+
+ /** @param {AnnotationTool} tool */
+ setAnnotationTool(tool) {
+ this.tool_ = tool;
+ if (this.inkHost_) {
+ this.inkHost_.setAnnotationTool(tool);
+ }
+ }
+
+ /** @override */
+ rotateClockwise() {
+ // TODO(dstockwell): implement rotation
+ }
+
+ /** @override */
+ rotateCounterclockwise() {
+ // TODO(dstockwell): implement rotation
+ }
+
+ /** @override */
+ viewportChanged() {
+ this.inkHost_.viewportChanged();
+ }
+
+ /** @override */
+ save(requireResult) {
+ return this.inkHost_.saveDocument();
+ }
+
+ /** @override */
+ undo() {
+ this.inkHost_.undo();
+ }
+
+ /** @override */
+ redo() {
+ this.inkHost_.redo();
+ }
+
+ /** @override */
+ load(filename, data) {
+ if (!this.inkHost_) {
+ const inkHost = document.createElement('viewer-ink-host');
+ $('content').appendChild(inkHost);
+ this.inkHost_ = /** @type {!ViewerInkHostElement} */ (inkHost);
+ this.inkHost_.viewport = this.viewport_;
+ inkHost.addEventListener('stroke-added', e => {
+ this.eventTarget_.dispatchEvent(new CustomEvent('has-unsaved-changes'));
+ });
+ inkHost.addEventListener('undo-state-changed', e => {
+ this.eventTarget_.dispatchEvent(
+ new CustomEvent('set-annotation-undo-state', {detail: e.detail}));
+ });
+ }
+ return this.inkHost_.load(filename, data);
+ }
+
+ /** @override */
+ unload() {
+ this.inkHost_.remove();
+ this.inkHost_ = null;
+ }
+}
+
+/**
+ * PDF plugin controller, responsible for communicating with the embedded plugin
+ * element. Dispatches a 'plugin-message' event containing the message from the
+ * plugin, if a message type not handled by this controller is received.
+ */
+class PluginController extends ContentController {
+ /**
+ * @param {!HTMLEmbedElement} plugin
+ * @param {!Viewport} viewport
+ * @param {function():boolean} getIsUserInitiatedCallback
+ * @param {function():?Promise} getLoadedCallback
+ */
+ constructor(plugin, viewport, getIsUserInitiatedCallback, getLoadedCallback) {
+ super();
+
+ /** @private {!HTMLEmbedElement} */
+ this.plugin_ = plugin;
+
+ /** @private {!Viewport} */
+ this.viewport_ = viewport;
+
+ /** @private {!function():boolean} */
+ this.getIsUserInitiatedCallback_ = getIsUserInitiatedCallback;
+
+ /** @private {!function():?Promise} */
+ this.getLoadedCallback_ = getLoadedCallback;
+
+ /** @private {!Map<string, PromiseResolver>} */
+ this.pendingTokens_ = new Map();
+ this.plugin_.addEventListener(
+ 'message', e => this.handlePluginMessage_(e), false);
+
+ /** @private {!EventTarget} */
+ this.eventTarget_ = new cr.EventTarget();
+ }
+
+ /** @return {!EventTarget} */
+ getEventTarget() {
+ return this.eventTarget_;
+ }
+
+ /**
+ * Notify the plugin to stop reacting to scroll events while zoom is taking
+ * place to avoid flickering.
+ * @override
+ */
+ beforeZoom() {
+ this.postMessage_({type: 'stopScrolling'});
+
+ if (this.viewport_.pinchPhase == Viewport.PinchPhase.PINCH_START) {
+ const position = this.viewport_.position;
+ const zoom = this.viewport_.getZoom();
+ const pinchPhase = this.viewport_.pinchPhase;
+ const layoutOptions = this.viewport_.getLayoutOptions();
+ this.postMessage_({
+ type: 'viewport',
+ userInitiated: true,
+ zoom: zoom,
+ layoutOptions: layoutOptions,
+ xOffset: position.x,
+ yOffset: position.y,
+ pinchPhase: pinchPhase
+ });
+ }
+ }
+
+ /**
+ * Notify the plugin of the zoom change and to continue reacting to scroll
+ * events.
+ * @override
+ */
+ afterZoom() {
+ const position = this.viewport_.position;
+ const zoom = this.viewport_.getZoom();
+ const layoutOptions = this.viewport_.getLayoutOptions();
+ const pinchVector = this.viewport_.pinchPanVector || {x: 0, y: 0};
+ const pinchCenter = this.viewport_.pinchCenter || {x: 0, y: 0};
+ const pinchPhase = this.viewport_.pinchPhase;
+
+ this.postMessage_({
+ type: 'viewport',
+ userInitiated: this.getIsUserInitiatedCallback_(),
+ zoom: zoom,
+ layoutOptions: layoutOptions,
+ xOffset: position.x,
+ yOffset: position.y,
+ pinchPhase: pinchPhase,
+ pinchX: pinchCenter.x,
+ pinchY: pinchCenter.y,
+ pinchVectorX: pinchVector.x,
+ pinchVectorY: pinchVector.y
+ });
+ }
+
+ /**
+ * Post a message to the PPAPI plugin. Some messages will cause an async reply
+ * to be received through handlePluginMessage_().
+ * @param {!MessageData} message Message to post.
+ * @private
+ */
+ postMessage_(message) {
+ this.plugin_.postMessage(message);
+ }
+
+ /** @override */
+ rotateClockwise() {
+ this.postMessage_({type: 'rotateClockwise'});
+ }
+
+ /** @override */
+ rotateCounterclockwise() {
+ this.postMessage_({type: 'rotateCounterclockwise'});
+ }
+
+ /** @override */
+ print() {
+ this.postMessage_({type: 'print'});
+ }
+
+ selectAll() {
+ this.postMessage_({type: 'selectAll'});
+ }
+
+ getSelectedText() {
+ this.postMessage_({type: 'getSelectedText'});
+ }
+
+ /** @param {!PrintPreviewParams} printPreviewParams */
+ resetPrintPreviewMode(printPreviewParams) {
+ this.postMessage_({
+ type: 'resetPrintPreviewMode',
+ url: printPreviewParams.url,
+ grayscale: printPreviewParams.grayscale,
+ // If the PDF isn't modifiable we send 0 as the page count so that no
+ // blank placeholder pages get appended to the PDF.
+ pageCount:
+ (printPreviewParams.modifiable ?
+ printPreviewParams.pageNumbers.length :
+ 0)
+ });
+ }
+
+ /** @param {string} newColor New color, in hex, for the PDF plugin. */
+ backgroundColorChanged(newColor) {
+ this.postMessage_({
+ type: 'backgroundColorChanged',
+ backgroundColor: newColor,
+ });
+ }
+
+ /**
+ * @param {string} url
+ * @param {number} index
+ */
+ loadPreviewPage(url, index) {
+ this.postMessage_({type: 'loadPreviewPage', url: url, index: index});
+ }
+
+ /** @param {string} password */
+ getPasswordComplete(password) {
+ this.postMessage_({type: 'getPasswordComplete', password: password});
+ }
+
+ /** @param {string} destination */
+ getNamedDestination(destination) {
+ this.postMessage_({
+ type: 'getNamedDestination',
+ namedDestination: destination,
+ });
+ }
+
+ /** @override */
+ save(requireResult) {
+ const resolver = new PromiseResolver();
+ const newToken = createToken();
+ this.pendingTokens_.set(newToken, resolver);
+ this.postMessage_({type: 'save', token: newToken, force: requireResult});
+ return resolver.promise;
+ }
+
+ /** @override */
+ async load(fileName, data) {
+ const url = URL.createObjectURL(new Blob([data]));
+ this.plugin_.removeAttribute('headers');
+ this.plugin_.setAttribute('stream-url', url);
+ this.plugin_.style.display = 'block';
+ try {
+ await this.getLoadedCallback_();
+ } finally {
+ URL.revokeObjectURL(url);
+ }
+ }
+
+ /** @override */
+ unload() {
+ this.plugin_.style.display = 'none';
+ }
+
+ /**
+ * An event handler for handling message events received from the plugin.
+ * @param {!Event} messageEvent a message event.
+ * @private
+ */
+ handlePluginMessage_(messageEvent) {
+ const messageData = /** @type {!MessageData} */ (messageEvent.data);
+ switch (messageData.type) {
+ case 'email':
+ const emailData = /** @type {!EmailMessageData} */ (messageData);
+ const href = 'mailto:' + emailData.to + '?cc=' + emailData.cc +
+ '&bcc=' + emailData.bcc + '&subject=' + emailData.subject +
+ '&body=' + emailData.body;
+ window.location.href = href;
+ break;
+ case 'goToPage':
+ this.viewport_.goToPage(
+ /** @type {{type: string, page: number}} */ (messageData).page);
+ break;
+ case 'setScrollPosition':
+ this.viewport_.scrollTo(/** @type {!PartialPoint} */ (messageData));
+ break;
+ case 'scrollBy':
+ this.viewport_.scrollBy(/** @type {!Point} */ (messageData));
+ break;
+ case 'saveData':
+ this.saveData_(/** @type {!SaveDataMessageData} */ (messageData));
+ break;
+ case 'consumeSaveToken':
+ const saveTokenData =
+ /** @type {{ type: string, token: string }} */ (messageData);
+ const resolver = this.pendingTokens_.get(saveTokenData.token);
+ assert(this.pendingTokens_.delete(saveTokenData.token));
+ resolver.resolve(null);
+ break;
+ default:
+ this.eventTarget_.dispatchEvent(
+ new CustomEvent('plugin-message', {detail: messageData}));
+ }
+ }
+
+ /**
+ * Handles the pdf file buffer received from the plugin.
+ *
+ * @param {!SaveDataMessageData} messageData data of the message event.
+ * @private
+ */
+ saveData_(messageData) {
+ assert(
+ loadTimeData.getBoolean('pdfFormSaveEnabled') ||
+ loadTimeData.getBoolean('pdfAnnotationsEnabled'));
+
+ // Verify a token that was created by this instance is included to avoid
+ // being spammed.
+ const resolver = this.pendingTokens_.get(messageData.token);
+ assert(this.pendingTokens_.delete(messageData.token));
+
+ if (!messageData.dataToSave) {
+ resolver.reject();
+ return;
+ }
+
+ // Verify the file size and the first bytes to make sure it's a PDF. Cap at
+ // 100 MB. This cap should be kept in sync with and is also enforced in
+ // pdf/out_of_process_instance.cc.
+ const MIN_FILE_SIZE = '%PDF1.0'.length;
+ const MAX_FILE_SIZE = 100 * 1000 * 1000;
+
+ const buffer = messageData.dataToSave;
+ const bufView = new Uint8Array(buffer);
+ assert(
+ bufView.length <= MAX_FILE_SIZE,
+ `File too large to be saved: ${bufView.length} bytes.`);
+ assert(bufView.length >= MIN_FILE_SIZE);
+ assert(
+ String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) ==
+ '%PDF');
+
+ resolver.resolve(messageData);
+ }
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn
new file mode 100644
index 00000000000..248059ae74f
--- /dev/null
+++ b/chromium/chrome/browser/resources/pdf/elements/BUILD.gn
@@ -0,0 +1,118 @@
+# 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 = [
+ ":viewer-bookmark",
+ ":viewer-error-screen",
+ ":viewer-page-indicator",
+ ":viewer-page-selector",
+ ":viewer-password-screen",
+ ":viewer-pdf-toolbar",
+ ":viewer-toolbar-dropdown",
+ ":viewer-zoom-button",
+ ":viewer-zoom-toolbar",
+ ]
+ if (is_chromeos) {
+ deps += [
+ ":viewer-form-warning",
+ ":viewer-ink-host",
+ ":viewer-pen-options",
+ ]
+ }
+}
+
+js_library("viewer-bookmark") {
+ deps = [
+ "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
+ ]
+}
+
+js_library("viewer-error-screen") {
+ deps = [
+ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+ ]
+}
+
+if (is_chromeos) {
+ js_library("viewer-form-warning") {
+ deps = [
+ "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
+ "//ui/webui/resources/js:promise_resolver",
+ ]
+ }
+
+ js_library("viewer-ink-host") {
+ deps = [
+ "//chrome/browser/resources/pdf:metrics",
+ "//chrome/browser/resources/pdf:viewport",
+ "//chrome/browser/resources/pdf/ink:ink_api",
+ ]
+ }
+}
+
+js_library("viewer-page-indicator") {
+ deps = [
+ "//ui/webui/resources/js:assert",
+ "//ui/webui/resources/js:util",
+ ]
+}
+
+js_library("viewer-page-selector") {
+ deps = [
+ "//ui/webui/resources/cr_elements/cr_input:cr_input",
+ ]
+}
+
+js_library("viewer-password-screen") {
+ deps = [
+ "//ui/webui/resources/cr_elements/cr_input:cr_input",
+ ]
+}
+
+js_library("viewer-pdf-toolbar") {
+ deps = [
+ ":viewer-bookmark",
+ ":viewer-page-selector",
+ ":viewer-toolbar-dropdown",
+ "..:annotation_tool",
+ ]
+ externs_list = [ "$externs_path/pending.js" ]
+}
+
+js_library("viewer-pen-options") {
+ externs_list = [ "$externs_path/pending_polymer.js" ]
+}
+
+js_library("viewer-toolbar-dropdown") {
+ deps = []
+}
+
+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 = []
+}
+
+polymer_modulizer("shared-vars") {
+ js_file = "shared-vars.m.js"
+ html_file = "shared-vars.html"
+ html_type = "custom-style"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":shared-vars_module",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html
index 004aa1b1677..004aa1b1677 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js
index f1cce48abaa..f25ebcef472 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark.js
@@ -7,8 +7,9 @@
*
* The bookmark may point at a location in the PDF or a URI.
* If it points at a location, |page| indicates which 0-based page it leads to.
- * Optionally, |y| is the y position in that page, in pixel coordinates.
- * If it points at an URI, |uri| is the target for that bookmark.
+ * Optionally, |x| is the x position in that page, |y| is the y position in that
+ * page, in pixel coordinates and |zoom| is the new zoom value. If it points at
+ * an URI, |uri| is the target for that bookmark.
*
* |children| is an array of the |Bookmark|s that are below this in a table of
* contents tree
@@ -16,7 +17,9 @@
* @typedef {{
* title: string,
* page: (number | undefined),
+ * x: (number | undefined),
* y: (number | undefined),
+ * zoom: (number | undefined),
* uri: (string | undefined),
* children: !Array<!Bookmark>
* }}
@@ -80,11 +83,15 @@ Polymer({
/** @private */
onClick_: function() {
- if (this.bookmark.hasOwnProperty('page')) {
- if (this.bookmark.hasOwnProperty('y')) {
+ if (this.bookmark.page != null) {
+ if (this.bookmark.zoom != null) {
+ this.fire('change-zoom', {zoom: this.bookmark.zoom});
+ }
+ if (this.bookmark.x != null &&
+ this.bookmark.y != null) {
this.fire('change-page-and-xy', {
page: this.bookmark.page,
- x: 0,
+ x: this.bookmark.x,
y: this.bookmark.y,
origin: 'bookmark'
});
@@ -92,7 +99,7 @@ Polymer({
this.fire(
'change-page', {page: this.bookmark.page, origin: 'bookmark'});
}
- } else if (this.bookmark.hasOwnProperty('uri')) {
+ } else if (this.bookmark.uri != null) {
this.fire('navigate', {uri: this.bookmark.uri, newtab: true});
}
},
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/BUILD.gn
deleted file mode 100644
index fa2b15b86f7..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-bookmark/BUILD.gn
+++ /dev/null
@@ -1,17 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-bookmark",
- ]
-}
-
-js_library("viewer-bookmark") {
- deps = [
- "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
- ]
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.html
index 25737d45127..25737d45127 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js
index 082220a4c92..082220a4c92 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/viewer-error-screen.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/BUILD.gn
deleted file mode 100644
index 3beeb5d21b0..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-error-screen/BUILD.gn
+++ /dev/null
@@ -1,17 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-error-screen",
- ]
-}
-
-js_library("viewer-error-screen") {
- deps = [
- "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
- ]
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.html b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.html
index 1e9e1ee4f67..1e9e1ee4f67 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.js b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js
index 539eddd6b67..539eddd6b67 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning/viewer-form-warning.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-form-warning.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.html b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.html
index 1a7a2ff73ea..1a7a2ff73ea 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/viewer-ink-host.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host.html
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.js
index 285edf8a35d..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.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/BUILD.gn
deleted file mode 100644
index 32ca2b04311..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-ink-host/BUILD.gn
+++ /dev/null
@@ -1,19 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-ink-host",
- ]
-}
-
-js_library("viewer-ink-host") {
- deps = [
- "//chrome/browser/resources/pdf:metrics",
- "//chrome/browser/resources/pdf:viewport",
- "//chrome/browser/resources/pdf/ink:ink_api",
- ]
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.html b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.html
index 70ad2578685..70ad2578685 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js
index 50ad4f4cb49..50ad4f4cb49 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/viewer-page-indicator.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/BUILD.gn
deleted file mode 100644
index aa1906c65e5..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-indicator/BUILD.gn
+++ /dev/null
@@ -1,18 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-page-indicator",
- ]
-}
-
-js_library("viewer-page-indicator") {
- deps = [
- "//ui/webui/resources/js:assert",
- "//ui/webui/resources/js:util",
- ]
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html
index e1fdc869efe..e1fdc869efe 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js
index b7999237a98..b7999237a98 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/viewer-page-selector.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/BUILD.gn
deleted file mode 100644
index 725e3f96591..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-page-selector/BUILD.gn
+++ /dev/null
@@ -1,17 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-page-selector",
- ]
-}
-
-js_library("viewer-page-selector") {
- deps = [
- "//ui/webui/resources/cr_elements/cr_input:cr_input",
- ]
-}
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.html
index aebc16bf138..aebc16bf138 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js
index 5506ad2915c..5506ad2915c 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/viewer-password-screen.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/BUILD.gn b/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/BUILD.gn
deleted file mode 100644
index 5078ae7403f..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-password-screen/BUILD.gn
+++ /dev/null
@@ -1,17 +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.
-
-import("//third_party/closure_compiler/compile_js.gni")
-
-js_type_check("closure_compile") {
- deps = [
- ":viewer-password-screen",
- ]
-}
-
-js_library("viewer-password-screen") {
- deps = [
- "//ui/webui/resources/cr_elements/cr_input:cr_input",
- ]
-}
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.html
index e183debc86d..348e2215fed 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.html
@@ -4,13 +4,13 @@
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
<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-bookmark/viewer-bookmark.html">
-<link rel="import" href="../viewer-page-selector/viewer-page-selector.html">
+<link rel="import" href="icons.html">
+<link rel="import" href="viewer-bookmark.html">
+<link rel="import" href="viewer-page-selector.html">
<if expr="chromeos">
-<link rel="import" href="../viewer-pen-options/viewer-pen-options.html">
+<link rel="import" href="viewer-pen-options.html">
</if>
-<link rel="import" href="../viewer-toolbar-dropdown/viewer-toolbar-dropdown.html">
+<link rel="import" href="viewer-toolbar-dropdown.html">
<dom-module id="viewer-pdf-toolbar">
<template>
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.js
index afb87dfe6b7..07407cfee75 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.js
@@ -1,6 +1,7 @@
// 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.
+
(function() {
Polymer({
is: 'viewer-pdf-toolbar',
@@ -24,7 +25,7 @@ Polymer({
reflectToAttribute: true,
},
- /** @type {?Object} */
+ /** @type {?AnnotationTool} */
annotationTool: {
type: Object,
value: null,
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
deleted file mode 100644
index fdc650f55b9..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/BUILD.gn
+++ /dev/null
@@ -1,20 +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.
-
-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-pen-options/viewer-pen-options.html b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.html
index dbf18b0bfda..dbf18b0bfda 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.html
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js
index 3970e0ff630..d63343404fb 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-pen-options.js
@@ -81,7 +81,7 @@ Polymer({
strings: Object,
},
- /** @type {Array<Animation>} */
+ /** @type {Array<!Animation>} */
expandAnimations_: null,
/** @param {Event} e */
@@ -103,7 +103,8 @@ Polymer({
/** @private */
updateExpandedStateAndFinishAnimations_: function() {
this.updateExpandedState_();
- for (const animation of this.expandAnimations_) {
+ for (const animation of /** @type {!Array<!Animation>} */ (
+ this.expandAnimations_)) {
animation.finish();
}
},
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.html
index 1ebf0df604f..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.html
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.js
index 00b2b676b45..191f4cfcfbf 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.js
@@ -216,5 +216,4 @@ Polymer({
});
}
});
-
})();
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-button.html
index 000d098cfb3..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-button.html
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-button.js
index 2359900d83c..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-button.js
diff --git a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html
index e0f2bdd15ba..0807c5dfe64 100644
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html
+++ b/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar.html
@@ -1,7 +1,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="icons.html">
<link rel="import" href="viewer-zoom-button.html">
<dom-module id="viewer-zoom-toolbar">
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.js
index fe24ab64645..fe28ef8c96a 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.js
@@ -2,6 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/**
+ * @typedef {{
+ * fittingType: !FittingType,
+ * userInitiated: boolean,
+ * }}
+ */
+let FitToChangedEvent;
+
(function() {
const FIT_TO_PAGE_BUTTON_STATE = 0;
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
deleted file mode 100644
index 4c75971c261..00000000000
--- a/chromium/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/BUILD.gn
+++ /dev/null
@@ -1,25 +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.
-
-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/index.html b/chromium/chrome/browser/resources/pdf/index.html
index 06d219a6c7e..00d96432fd0 100644
--- a/chromium/chrome/browser/resources/pdf/index.html
+++ b/chromium/chrome/browser/resources/pdf/index.html
@@ -4,20 +4,20 @@
<meta charset="utf-8">
<script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js">
</script>
- <link rel="import" href="elements/viewer-error-screen/viewer-error-screen.html">
- <link rel="import" href="elements/viewer-page-indicator/viewer-page-indicator.html">
- <link rel="import" href="elements/viewer-page-selector/viewer-page-selector.html">
- <link rel="import" href="elements/viewer-password-screen/viewer-password-screen.html">
- <link rel="import" href="elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html">
- <link rel="import" href="elements/viewer-zoom-toolbar/viewer-zoom-toolbar.html">
+ <link rel="import" href="elements/viewer-error-screen.html">
+ <link rel="import" href="elements/viewer-page-indicator.html">
+ <link rel="import" href="elements/viewer-page-selector.html">
+ <link rel="import" href="elements/viewer-password-screen.html">
+ <link rel="import" href="elements/viewer-pdf-toolbar.html">
+ <link rel="import" href="elements/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">
- <link rel="import" href="elements/viewer-form-warning/viewer-form-warning.html">
+ <link rel="import" href="elements/viewer-ink-host.html">
+ <link rel="import" href="elements/viewer-form-warning.html">
</if>
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
@@ -58,6 +58,7 @@
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="browser_api.js"></script>
<script src="metrics.js"></script>
+<script src="controller.js"></script>
<script src="pdf_viewer.js"></script>
<script src="main.js"></script>
</html>
diff --git a/chromium/chrome/browser/resources/pdf/ink/BUILD.gn b/chromium/chrome/browser/resources/pdf/ink/BUILD.gn
index 38908ee25a1..b1c2be215bd 100644
--- a/chromium/chrome/browser/resources/pdf/ink/BUILD.gn
+++ b/chromium/chrome/browser/resources/pdf/ink/BUILD.gn
@@ -11,6 +11,9 @@ js_type_check("closure_compile") {
}
js_library("ink_api") {
+ deps = [
+ "..:annotation_tool",
+ ]
externs_list = [
"//third_party/ink/build/ink_lib_externs.js",
"$externs_path/pending.js",
diff --git a/chromium/chrome/browser/resources/pdf/ink/ink_api.js b/chromium/chrome/browser/resources/pdf/ink/ink_api.js
index 04e0d56dcf6..99eed15d900 100644
--- a/chromium/chrome/browser/resources/pdf/ink/ink_api.js
+++ b/chromium/chrome/browser/resources/pdf/ink/ink_api.js
@@ -4,15 +4,6 @@
/**
* @typedef {{
- * tool: string,
- * size: number,
- * color: string,
- * }}
- */
-let AnnotationTool;
-
-/**
- * @typedef {{
* canUndo: boolean,
* canRedo: boolean,
* }}
@@ -88,7 +79,7 @@ class InkAPI {
}[tool.tool];
this.brush_.setShape(shape);
if (tool.tool != 'eraser') {
- this.brush_.setColor(tool.color);
+ this.brush_.setColor(/** @type {string} */ (tool.color));
}
this.brush_.setStrokeWidth(tool.size);
}
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 d4a502a135f..c33c46b6d75 100644
--- a/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
+++ b/chromium/chrome/browser/resources/pdf/open_pdf_params_parser.js
@@ -10,15 +10,15 @@
*/
class OpenPdfParamsParser {
/**
- * @param {function(Object)} postMessageCallback
+ * @param {function(string):void} getNamedDestinationCallback
* Function called to fetch information for a named destination.
*/
- constructor(postMessageCallback) {
+ constructor(getNamedDestinationCallback) {
/** @private {!Array<!Object>} */
this.outstandingRequests_ = [];
- /** @private {!function(Object)} */
- this.postMessageCallback_ = postMessageCallback;
+ /** @private {!function(string):void} */
+ this.getNamedDestinationCallback_ = getNamedDestinationCallback;
}
/**
@@ -181,10 +181,7 @@ class OpenPdfParamsParser {
if (params.page === undefined && 'nameddest' in urlParams) {
this.outstandingRequests_.push({callback: callback, params: params});
- this.postMessageCallback_({
- type: 'getNamedDestination',
- namedDestination: urlParams['nameddest']
- });
+ this.getNamedDestinationCallback_(urlParams['nameddest']);
} else {
callback(params);
}
diff --git a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
index 0ab77f41f3f..5957e13c178 100644
--- a/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
+++ b/chromium/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -6,7 +6,7 @@
* Turn a dictionary received from postMessage into a key event.
*
* @param {Object} dict A dictionary representing the key event.
- * @return {Event} A key event.
+ * @return {!Event} A key event.
*/
function DeserializeKeyEvent(dict) {
const e = document.createEvent('Event');
@@ -53,66 +53,83 @@ const LoadState = {
* Create a new PDFScriptingAPI. This provides a scripting interface to
* the PDF viewer so that it can be customized by things like print preview.
*
- * @param {Window} window the window of the page containing the pdf viewer.
- * @param {Object} plugin the plugin element containing the pdf viewer.
- * @constructor
*/
-function PDFScriptingAPI(window, plugin) {
- this.loadState_ = LoadState.LOADING;
- this.pendingScriptingMessages_ = [];
- this.setPlugin(plugin);
+class PDFScriptingAPI {
+ /**
+ * @param {Window} window the window of the page containing the pdf viewer.
+ * @param {Object} plugin the plugin element containing the pdf viewer.
+ */
+ constructor(window, plugin) {
+ this.loadState_ = LoadState.LOADING;
+ this.pendingScriptingMessages_ = [];
+ this.setPlugin(plugin);
- window.addEventListener('message', event => {
- if (event.origin != 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' &&
- event.origin != 'chrome://print') {
- console.error(
- 'Received message that was not from the extension: ' + event);
- return;
- }
- switch (event.data.type) {
- case 'viewport':
- /**
- * @type {{
- * pageX: number,
- * pageY: number,
- * pageWidth: number,
- * viewportWidth: number,
- * viewportHeight: number
- * }}
- */
- const viewportData = event.data;
- if (this.viewportChangedCallback_) {
- this.viewportChangedCallback_(
- viewportData.pageX, viewportData.pageY, viewportData.pageWidth,
- viewportData.viewportWidth, viewportData.viewportHeight);
- }
- break;
- case 'documentLoaded': {
- const data = /** @type {{load_state: LoadState}} */ (event.data);
- this.loadState_ = data.load_state;
- if (this.loadCallback_) {
- this.loadCallback_(this.loadState_ == LoadState.SUCCESS);
- }
- break;
+ /** @private {Function} */
+ this.viewportChangedCallback_;
+
+ /** @private {Function} */
+ this.loadCallback_;
+
+ /** @private {Function} */
+ this.selectedTextCallback_;
+
+ /** @private {Function} */
+ this.keyEventCallback_;
+
+ /** @private {Object} */
+ this.plugin_;
+
+ window.addEventListener('message', event => {
+ if (event.origin !=
+ 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai' &&
+ event.origin != 'chrome://print') {
+ console.error(
+ 'Received message that was not from the extension: ' + event);
+ return;
}
- case 'getSelectedTextReply': {
- const data = /** @type {{selectedText: string}} */ (event.data);
- if (this.selectedTextCallback_) {
- this.selectedTextCallback_(data.selectedText);
- this.selectedTextCallback_ = null;
+ switch (event.data.type) {
+ case 'viewport':
+ /**
+ * @type {{
+ * pageX: number,
+ * pageY: number,
+ * pageWidth: number,
+ * viewportWidth: number,
+ * viewportHeight: number
+ * }}
+ */
+ const viewportData = event.data;
+ if (this.viewportChangedCallback_) {
+ this.viewportChangedCallback_(
+ viewportData.pageX, viewportData.pageY, viewportData.pageWidth,
+ viewportData.viewportWidth, viewportData.viewportHeight);
+ }
+ break;
+ case 'documentLoaded': {
+ const data = /** @type {{load_state: LoadState}} */ (event.data);
+ this.loadState_ = data.load_state;
+ if (this.loadCallback_) {
+ this.loadCallback_(this.loadState_ == LoadState.SUCCESS);
+ }
+ break;
}
- break;
- }
- case 'sendKeyEvent':
- if (this.keyEventCallback_) {
- this.keyEventCallback_(DeserializeKeyEvent(event.data.keyEvent));
+ case 'getSelectedTextReply': {
+ const data = /** @type {{selectedText: string}} */ (event.data);
+ if (this.selectedTextCallback_) {
+ this.selectedTextCallback_(data.selectedText);
+ this.selectedTextCallback_ = null;
+ }
+ break;
}
- break;
- }
- }, false);
-}
+ case 'sendKeyEvent':
+ if (this.keyEventCallback_) {
+ this.keyEventCallback_(DeserializeKeyEvent(event.data.keyEvent));
+ }
+ break;
+ }
+ }, false);
+ }
-PDFScriptingAPI.prototype = {
/**
* Send a message to the extension. If messages try to get sent before there
* is a plugin element set, then we queue them up and send them later (this
@@ -121,13 +138,13 @@ PDFScriptingAPI.prototype = {
* @param {Object} message The message to send.
* @private
*/
- sendMessage_: function(message) {
+ sendMessage_(message) {
if (this.plugin_) {
this.plugin_.postMessage(message, '*');
} else {
this.pendingScriptingMessages_.push(message);
}
- },
+ }
/**
* Sets the plugin element containing the PDF viewer. The element will usually
@@ -135,7 +152,7 @@ PDFScriptingAPI.prototype = {
*
* @param {Object} plugin the plugin element containing the PDF viewer.
*/
- setPlugin: function(plugin) {
+ setPlugin(plugin) {
this.plugin_ = plugin;
if (this.plugin_) {
@@ -147,16 +164,16 @@ PDFScriptingAPI.prototype = {
this.sendMessage_(this.pendingScriptingMessages_.shift());
}
}
- },
+ }
/**
* Sets the callback which will be run when the PDF viewport changes.
*
* @param {Function} callback the callback to be called.
*/
- setViewportChangedCallback: function(callback) {
+ setViewportChangedCallback(callback) {
this.viewportChangedCallback_ = callback;
- },
+ }
/**
* Sets the callback which will be run when the PDF document has finished
@@ -164,20 +181,20 @@ PDFScriptingAPI.prototype = {
*
* @param {Function} callback the callback to be called.
*/
- setLoadCallback: function(callback) {
+ setLoadCallback(callback) {
this.loadCallback_ = callback;
if (this.loadState_ != LoadState.LOADING && this.loadCallback_) {
this.loadCallback_(this.loadState_ == LoadState.SUCCESS);
}
- },
+ }
/**
* Sets a callback that gets run when a key event is fired in the PDF viewer.
* @param {Function} callback the callback to be called with a key event.
*/
- setKeyEventCallback: function(callback) {
+ setKeyEventCallback(callback) {
this.keyEventCallback_ = callback;
- },
+ }
/**
* Resets the PDF viewer into print preview mode.
@@ -187,7 +204,7 @@ PDFScriptingAPI.prototype = {
* @param {Array<number>} pageNumbers an array of the page numbers.
* @param {boolean} modifiable whether or not the document is modifiable.
*/
- resetPrintPreviewMode: function(url, grayscale, pageNumbers, modifiable) {
+ resetPrintPreviewMode(url, grayscale, pageNumbers, modifiable) {
this.loadState_ = LoadState.LOADING;
this.sendMessage_({
type: 'resetPrintPreviewMode',
@@ -196,14 +213,14 @@ PDFScriptingAPI.prototype = {
pageNumbers: pageNumbers,
modifiable: modifiable
});
- },
+ }
/**
* Hide the toolbars after a delay.
*/
- hideToolbars: function() {
+ hideToolbars() {
this.sendMessage_({type: 'hideToolbars'});
- },
+ }
/**
* Load a page into the document while in print preview mode.
@@ -211,22 +228,22 @@ PDFScriptingAPI.prototype = {
* @param {string} url the url of the pdf page to load.
* @param {number} index the index of the page to load.
*/
- loadPreviewPage: function(url, index) {
+ loadPreviewPage(url, index) {
this.sendMessage_({type: 'loadPreviewPage', url: url, index: index});
- },
+ }
/** @param {boolean} darkMode Whether the page is in dark mode. */
- darkModeChanged: function(darkMode) {
+ darkModeChanged(darkMode) {
this.sendMessage_({type: 'darkModeChanged', darkMode: darkMode});
- },
+ }
/**
* Select all the text in the document. May only be called after document
* load.
*/
- selectAll: function() {
+ selectAll() {
this.sendMessage_({type: 'selectAll'});
- },
+ }
/**
* Get the selected text in the document. The callback will be called with the
@@ -236,40 +253,40 @@ PDFScriptingAPI.prototype = {
* @return {boolean} true if the function is successful, false if there is an
* outstanding request for selected text that has not been answered.
*/
- getSelectedText: function(callback) {
+ getSelectedText(callback) {
if (this.selectedTextCallback_) {
return false;
}
this.selectedTextCallback_ = callback;
this.sendMessage_({type: 'getSelectedText'});
return true;
- },
+ }
/**
* Print the document. May only be called after document load.
*/
- print: function() {
+ print() {
this.sendMessage_({type: 'print'});
- },
+ }
/**
* Send a key event to the extension.
*
* @param {Event} keyEvent the key event to send to the extension.
*/
- sendKeyEvent: function(keyEvent) {
+ sendKeyEvent(keyEvent) {
this.sendMessage_(
{type: 'sendKeyEvent', keyEvent: SerializeKeyEvent(keyEvent)});
- },
+ }
/**
* @param {number} scrollX The amount to horizontally scroll in pixels.
* @param {number} scrollY The amount to vertically scroll in pixels.
*/
- scrollPosition: function(scrollX, scrollY) {
+ scrollPosition(scrollX, scrollY) {
this.sendMessage_({type: 'scrollPosition', x: scrollX, y: scrollY});
- },
-};
+ }
+}
/**
* Creates a PDF viewer with a scripting interface. This is basically 1) an
diff --git a/chromium/chrome/browser/resources/pdf/pdf_viewer.js b/chromium/chrome/browser/resources/pdf/pdf_viewer.js
index 375663f029c..d85d80a2101 100644
--- a/chromium/chrome/browser/resources/pdf/pdf_viewer.js
+++ b/chromium/chrome/browser/resources/pdf/pdf_viewer.js
@@ -6,16 +6,64 @@
/**
* @typedef {{
- * dataToSave: Array,
- * token: string,
- * fileName: string
+ * source: Object,
+ * origin: string,
+ * data: !MessageData,
* }}
*/
-let SaveDataMessageData;
+let MessageObject;
/**
- * @return {number} Width of a scrollbar in pixels
+ * @typedef {{
+ * type: string,
+ * height: number,
+ * width: number,
+ * layoutOptions: (!LayoutOptions|undefined),
+ * pageDimensions: Array
+ * }}
+ */
+let DocumentDimensionsMessageData;
+
+/**
+ * @typedef {{
+ * type: string,
+ * url: string,
+ * disposition: !PdfNavigator.WindowOpenDisposition,
+ * }}
+ */
+let NavigateMessageData;
+
+/**
+ * @typedef {{
+ * type: string,
+ * page: number,
+ * x: number,
+ * y: number,
+ * zoom: number
+ * }}
+ */
+let DestinationMessageData;
+
+/**
+ * @typedef {{
+ * type: string,
+ * title: string,
+ * bookmarks: !Array<!Bookmark>,
+ * canSerializeDocument: boolean,
+ * }}
*/
+let MetadataMessageData;
+
+/**
+ * @typedef {{
+ * hasUnsavedChanges: (boolean|undefined),
+ * fileName: string,
+ * dataToSave: !ArrayBuffer
+ * }}
+ */
+let RequiredSaveResult;
+
+/** @return {number} Width of a scrollbar in pixels */
function getScrollbarWidth() {
const div = document.createElement('div');
div.style.visibility = 'hidden';
@@ -31,7 +79,6 @@ function getScrollbarWidth() {
/**
* Return the filename component of a URL, percent decoded if possible.
- *
* @param {string} url The URL to get the filename from.
* @return {string} The filename component.
*/
@@ -53,8 +100,7 @@ function getFilenameFromURL(url) {
/**
* Whether keydown events should currently be ignored. Events are ignored when
* an editable element has focus, to allow for proper editing controls.
- *
- * @param {HTMLElement} activeElement The currently selected DOM node.
+ * @param {Element} activeElement The currently selected DOM node.
* @return {boolean} True if keydown events should be ignored.
*/
function shouldIgnoreKeyEvents(activeElement) {
@@ -70,285 +116,341 @@ function shouldIgnoreKeyEvents(activeElement) {
}
/**
- * Creates a cryptographically secure pseudorandom 128-bit token.
- *
- * @return {string} The generated token as a hex string.
+ * Creates a new PDFViewer. There should only be one of these objects per
+ * document.
*/
-function createToken() {
- const randomBytes = new Uint8Array(16);
- return window.crypto.getRandomValues(randomBytes)
- .map(b => b.toString(16).padStart(2, '0'))
- .join('');
-}
+class PDFViewer {
+ /**
+ * @param {!BrowserApi} browserApi An object providing an API to the browser.
+ */
+ constructor(browserApi) {
+ /** @private {!BrowserApi} */
+ this.browserApi_ = browserApi;
-/**
- * The minimum number of pixels to offset the toolbar by from the bottom and
- * right side of the screen.
- */
-PDFViewer.MIN_TOOLBAR_OFFSET = 15;
+ /** @private {string} */
+ this.originalUrl_ = this.browserApi_.getStreamInfo().originalUrl;
-/**
- * The height of the toolbar along the top of the page. The document will be
- * shifted down by this much in the viewport.
- */
-PDFViewer.MATERIAL_TOOLBAR_HEIGHT = 56;
+ /** @private {string} */
+ this.javascript_ = this.browserApi_.getStreamInfo().javascript || 'block';
-/**
- * Minimum height for the material toolbar to show (px). Should match the media
- * query in index-material.css. If the window is smaller than this at load,
- * leave no space for the toolbar.
- */
-PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT = 250;
+ /** @private {!LoadState} */
+ this.loadState_ = LoadState.LOADING;
-/**
- * The background color used for print preview (--google-grey-refresh-300).
- */
-PDFViewer.PRINT_PREVIEW_BACKGROUND_COLOR = '0xFFDADCE0';
+ /** @private {?Object} */
+ this.parentWindow_ = null;
-/**
- * The background color used for print preview when dark mode is enabled
- * (--google-grey-refresh-700).
- */
-PDFViewer.PRINT_PREVIEW_DARK_BACKGROUND_COLOR = '0xFF5F6368';
+ /** @private {?string} */
+ this.parentOrigin_ = null;
-/**
- * The background color used for the regular viewer.
- */
-PDFViewer.BACKGROUND_COLOR = '0xFF525659';
+ /** @private {boolean} */
+ this.isFormFieldFocused_ = false;
-/**
- * Creates a new PDFViewer. There should only be one of these objects per
- * document.
- *
- * @param {!BrowserApi} browserApi An object providing an API to the browser.
- * @constructor
- */
-function PDFViewer(browserApi) {
- this.browserApi_ = browserApi;
- this.originalUrl_ = this.browserApi_.getStreamInfo().originalUrl;
- this.javascript_ = this.browserApi_.getStreamInfo().javascript || 'block';
- this.loadState_ = LoadState.LOADING;
- this.parentWindow_ = null;
- this.parentOrigin_ = null;
- this.isFormFieldFocused_ = false;
- this.beepCount_ = 0;
- this.delayedScriptingMessages_ = [];
- this.loaded_ = new PromiseResolver();
-
- this.isPrintPreview_ = location.origin === 'chrome://print';
- this.isPrintPreviewLoadingFinished_ = false;
- this.isUserInitiatedEvent_ = true;
-
- /** @private {boolean} */
- this.hasEnteredAnnotationMode_ = false;
-
- /** @private {boolean} */
- this.hadPassword_ = false;
-
- /** @private {boolean} */
- this.canSerializeDocument_ = false;
-
- PDFMetrics.record(PDFMetrics.UserAction.DOCUMENT_OPENED);
-
- // Parse open pdf parameters.
- this.paramsParser_ = new OpenPdfParamsParser(
- message => this.pluginController_.postMessage(message));
- const toolbarEnabled =
- this.paramsParser_.getUiUrlParams(this.originalUrl_).toolbar &&
- !this.isPrintPreview_;
-
- // The sizer element is placed behind the plugin element to cause scrollbars
- // 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', 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) {
- this.errorScreen_.reloadFn = () => {
- chrome.tabs.reload(this.browserApi_.getStreamInfo().tabId);
- };
- }
+ /** @private {number} */
+ this.beepCount_ = 0;
- // Create the viewport.
- const shortWindow = window.innerHeight < PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT;
- const topToolbarHeight =
- (toolbarEnabled) ? PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0;
- const defaultZoom =
- this.browserApi_.getZoomBehavior() == BrowserApi.ZoomBehavior.MANAGE ?
- this.browserApi_.getDefaultZoom() :
- 1.0;
- 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
- // positioning, acting as a viewport. The plugin renders into this viewport
- // according to the scroll position of the window.
- this.plugin_ = document.createElement('embed');
- // NOTE: The plugin's 'id' field must be set to 'plugin' since
- // chrome/renderer/printing/print_render_frame_helper.cc actually
- // references it.
- this.plugin_.id = 'plugin';
- this.plugin_.type = 'application/x-google-chrome-pdf';
-
- // Handle scripting messages from outside the extension that wish to interact
- // with it. We also send a message indicating that extension has loaded and
- // is ready to receive messages.
- window.addEventListener(
- 'message', message => this.handleScriptingMessage(message), false);
-
- this.plugin_.setAttribute('src', this.originalUrl_);
- this.plugin_.setAttribute(
- 'stream-url', this.browserApi_.getStreamInfo().streamUrl);
- let headers = '';
- for (const header in this.browserApi_.getStreamInfo().responseHeaders) {
- headers += header + ': ' +
- this.browserApi_.getStreamInfo().responseHeaders[header] + '\n';
- }
- this.plugin_.setAttribute('headers', headers);
+ /** @private {!Array} */
+ this.delayedScriptingMessages_ = [];
+
+ /** @private {!PromiseResolver} */
+ this.loaded_;
+
+ /** @private {boolean} */
+ this.initialLoadComplete_ = false;
+
+ /** @private {boolean} */
+ this.isPrintPreview_ = location.origin === 'chrome://print';
- this.plugin_.setAttribute('background-color', PDFViewer.BACKGROUND_COLOR);
- this.plugin_.setAttribute('top-toolbar-height', topToolbarHeight);
- this.plugin_.setAttribute('javascript', this.javascript_);
+ /** @private {boolean} */
+ this.isPrintPreviewLoadingFinished_ = false;
- if (this.browserApi_.getStreamInfo().embedded) {
+ /** @private {boolean} */
+ this.isUserInitiatedEvent_ = true;
+
+ /** @private {boolean} */
+ this.hasEnteredAnnotationMode_ = false;
+
+ /** @private {boolean} */
+ this.hadPassword_ = false;
+
+ /** @private {boolean} */
+ this.canSerializeDocument_ = false;
+
+ /** @private {!EventTracker} */
+ this.tracker_ = new EventTracker();
+
+ PDFMetrics.record(PDFMetrics.UserAction.DOCUMENT_OPENED);
+
+ // Parse open pdf parameters.
+ /** @private {!OpenPdfParamsParser} */
+ this.paramsParser_ = new OpenPdfParamsParser(
+ destination => this.pluginController_.getNamedDestination(destination));
+ const toolbarEnabled =
+ this.paramsParser_.getUiUrlParams(this.originalUrl_).toolbar &&
+ !this.isPrintPreview_;
+
+ // The sizer element is placed behind the plugin element to cause scrollbars
+ // to be displayed in the window. It is sized according to the document size
+ // of the pdf and zoom level.
+ this.sizer_ = /** @type {!HTMLDivElement} */ ($('sizer'));
+
+ /** @private {?ViewerPageIndicatorElement} */
+ this.pageIndicator_ = this.isPrintPreview_ ?
+ /** @type {!ViewerPageIndicatorElement} */ ($('page-indicator')) :
+ null;
+
+ /** @private {?ViewerPasswordScreenElement} */
+ this.passwordScreen_ =
+ /** @type {!ViewerPasswordScreenElement} */ ($('password-screen'));
+ this.passwordScreen_.addEventListener('password-submitted', e => {
+ this.onPasswordSubmitted_(
+ /** @type {!CustomEvent<{password: string}>} */ (e));
+ });
+
+ /** @private {?ViewerErrorScreenElement} */
+ this.errorScreen_ =
+ /** @type {!ViewerErrorScreenElement} */ ($('error-screen'));
+ // Can only reload if we are in a normal tab.
+ if (chrome.tabs && this.browserApi_.getStreamInfo().tabId != -1) {
+ this.errorScreen_.reloadFn = () => {
+ chrome.tabs.reload(this.browserApi_.getStreamInfo().tabId);
+ };
+ }
+
+ // Create the viewport.
+ const shortWindow =
+ window.innerHeight < PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT;
+ const topToolbarHeight =
+ (toolbarEnabled) ? PDFViewer.MATERIAL_TOOLBAR_HEIGHT : 0;
+ const defaultZoom =
+ this.browserApi_.getZoomBehavior() == BrowserApi.ZoomBehavior.MANAGE ?
+ this.browserApi_.getDefaultZoom() :
+ 1.0;
+
+ /** @private {!Viewport} */
+ 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.resetTrackers_());
+
+ // 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
+ // positioning, acting as a viewport. The plugin renders into this viewport
+ // according to the scroll position of the window.
+ /** @private {!HTMLEmbedElement} */
+ this.plugin_ =
+ /** @type {!HTMLEmbedElement} */ (document.createElement('embed'));
+
+ // NOTE: The plugin's 'id' field must be set to 'plugin' since
+ // chrome/renderer/printing/print_render_frame_helper.cc actually
+ // references it.
+ this.plugin_.id = 'plugin';
+ this.plugin_.type = 'application/x-google-chrome-pdf';
+
+ // Handle scripting messages from outside the extension that wish to
+ // interact with it. We also send a message indicating that extension has
+ // loaded and is ready to receive messages.
+ window.addEventListener('message', message => {
+ this.handleScriptingMessage(/** @type {!MessageObject} */ (message));
+ }, false);
+
+ this.plugin_.setAttribute('src', this.originalUrl_);
this.plugin_.setAttribute(
- 'top-level-url', this.browserApi_.getStreamInfo().tabUrl);
- } else {
- this.plugin_.setAttribute('full-frame', '');
- }
+ 'stream-url', this.browserApi_.getStreamInfo().streamUrl);
+ let headers = '';
+ for (const header in this.browserApi_.getStreamInfo().responseHeaders) {
+ headers += header + ': ' +
+ this.browserApi_.getStreamInfo().responseHeaders[header] + '\n';
+ }
+ this.plugin_.setAttribute('headers', headers);
- $('content').appendChild(this.plugin_);
-
- this.pluginController_ =
- new PluginController(this.plugin_, this, this.viewport_);
- this.inkController_ = new InkController(this, this.viewport_);
- this.currentController_ = this.pluginController_;
-
- // Setup the button event listeners.
- this.zoomToolbar_ = $('zoom-toolbar');
- this.zoomToolbar_.setIsPrintPreview(this.isPrintPreview_);
- this.zoomToolbar_.addEventListener(
- 'fit-to-changed', e => this.fitToChanged_(e));
- this.zoomToolbar_.addEventListener('zoom-in', () => this.viewport_.zoomIn());
- this.zoomToolbar_.addEventListener(
- 'zoom-out', () => this.viewport_.zoomOut());
-
- this.gestureDetector_ = new GestureDetector($('content'));
- this.gestureDetector_.addEventListener(
- 'pinchstart', e => this.onPinchStart_(e));
- this.sentPinchEvent_ = false;
- this.gestureDetector_.addEventListener(
- 'pinchupdate', e => this.onPinchUpdate_(e));
- this.gestureDetector_.addEventListener('pinchend', e => this.onPinchEnd_(e));
-
- if (toolbarEnabled) {
- this.toolbar_ = $('toolbar');
- this.toolbar_.hidden = false;
- this.toolbar_.addEventListener('save', () => this.save());
- this.toolbar_.addEventListener('print', () => this.print());
- this.toolbar_.addEventListener(
- 'undo', () => this.currentController_.undo());
- this.toolbar_.addEventListener(
- 'redo', () => this.currentController_.redo());
- this.toolbar_.addEventListener(
- 'rotate-right', () => this.rotateClockwise());
- this.toolbar_.addEventListener(
- 'annotation-mode-toggled', e => this.annotationModeToggled_(e));
- this.toolbar_.addEventListener(
- 'annotation-tool-changed',
- e => this.inkController_.setAnnotationTool(e.detail.value));
-
- this.toolbar_.docTitle = getFilenameFromURL(this.originalUrl_);
- }
+ this.plugin_.setAttribute('background-color', PDFViewer.BACKGROUND_COLOR);
+ this.plugin_.setAttribute('top-toolbar-height', topToolbarHeight);
+ this.plugin_.setAttribute('javascript', this.javascript_);
- document.body.addEventListener('change-page', e => {
- this.viewport_.goToPage(e.detail.page);
- if (e.detail.origin == 'bookmark') {
- PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK);
- } else if (e.detail.origin == 'pageselector') {
- PDFMetrics.record(PDFMetrics.UserAction.PAGE_SELECTOR_NAVIGATE);
+ if (this.browserApi_.getStreamInfo().embedded) {
+ this.plugin_.setAttribute(
+ 'top-level-url', this.browserApi_.getStreamInfo().tabUrl);
+ } else {
+ this.plugin_.setAttribute('full-frame', '');
}
- });
-
- document.body.addEventListener('change-page-and-xy', e => {
- const point = this.viewport_.convertPageToScreen(e.detail.page, e.detail);
- this.goToPageAndXY_(e.detail.origin, e.detail.page, point);
- });
-
- document.body.addEventListener('navigate', e => {
- const disposition = e.detail.newtab ?
- PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
- PdfNavigator.WindowOpenDisposition.CURRENT_TAB;
- this.navigator_.navigate(e.detail.uri, disposition);
- });
-
- document.body.addEventListener('dropdown-opened', e => {
- if (e.detail == 'bookmarks') {
- PDFMetrics.record(PDFMetrics.UserAction.OPEN_BOOKMARKS_PANEL);
+
+ $('content').appendChild(this.plugin_);
+
+ /** @private {!PluginController} */
+ this.pluginController_ = new PluginController(
+ this.plugin_, this.viewport_, () => this.isUserInitiatedEvent_,
+ () => this.loaded);
+ this.tracker_.add(
+ this.pluginController_.getEventTarget(), 'plugin-message',
+ e => this.handlePluginMessage_(e));
+
+ /** @private {!InkController} */
+ this.inkController_ = new InkController(this.viewport_);
+ this.tracker_.add(
+ this.inkController_.getEventTarget(), 'stroke-added',
+ () => chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(true));
+ this.tracker_.add(
+ this.inkController_.getEventTarget(), 'set-annotation-undo-state',
+ e => this.setAnnotationUndoState_(e));
+
+ /** @private {!ContentController} */
+ this.currentController_ = this.pluginController_;
+
+ // Setup the button event listeners.
+ /** @private {!ViewerZoomToolbarElement} */
+ this.zoomToolbar_ =
+ /** @type {!ViewerZoomToolbarElement} */ ($('zoom-toolbar'));
+ this.zoomToolbar_.setIsPrintPreview(this.isPrintPreview_);
+ this.zoomToolbar_.addEventListener(
+ 'fit-to-changed',
+ e => this.fitToChanged_(
+ /** @type {!CustomEvent<FitToChangedEvent>}} */ (e)));
+ this.zoomToolbar_.addEventListener(
+ 'zoom-in', () => this.viewport_.zoomIn());
+ this.zoomToolbar_.addEventListener(
+ 'zoom-out', () => this.viewport_.zoomOut());
+
+ /** @private {!GestureDetector} */
+ this.gestureDetector_ = new GestureDetector(assert($('content')));
+ this.gestureDetector_.addEventListener(
+ 'pinchstart', e => this.onPinchStart_(e));
+ this.sentPinchEvent_ = false;
+ this.gestureDetector_.addEventListener(
+ 'pinchupdate', e => this.onPinchUpdate_(e));
+ this.gestureDetector_.addEventListener(
+ 'pinchend', e => this.onPinchEnd_(e));
+
+ /** @private {?ViewerPdfToolbarElement} */
+ this.toolbar_ = null;
+ if (toolbarEnabled) {
+ this.toolbar_ = /** @type {!ViewerPdfToolbarElement} */ ($('toolbar'));
+ this.toolbar_.hidden = false;
+ this.toolbar_.addEventListener('save', () => this.save_());
+ this.toolbar_.addEventListener('print', () => this.print_());
+ this.toolbar_.addEventListener(
+ 'undo', () => this.currentController_.undo());
+ this.toolbar_.addEventListener(
+ 'redo', () => this.currentController_.redo());
+ this.toolbar_.addEventListener(
+ 'rotate-right', () => this.rotateClockwise_());
+ this.toolbar_.addEventListener('annotation-mode-toggled', e => {
+ this.annotationModeToggled_(
+ /** @type {!CustomEvent<{value: boolean}>} */ (e));
+ });
+ this.toolbar_.addEventListener(
+ 'annotation-tool-changed',
+ e => this.inkController_.setAnnotationTool(e.detail.value));
+
+ this.toolbar_.docTitle = getFilenameFromURL(this.originalUrl_);
+ }
+
+ document.body.addEventListener('change-page', e => {
+ this.viewport_.goToPage(e.detail.page);
+ if (e.detail.origin == 'bookmark') {
+ PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK);
+ } else if (e.detail.origin == 'pageselector') {
+ PDFMetrics.record(PDFMetrics.UserAction.PAGE_SELECTOR_NAVIGATE);
+ }
+ });
+
+ document.body.addEventListener('change-zoom', e => {
+ this.viewport_.setZoom(e.detail.zoom);
+ });
+
+ document.body.addEventListener('change-page-and-xy', e => {
+ const point = this.viewport_.convertPageToScreen(e.detail.page, e.detail);
+ this.goToPageAndXY_(e.detail.origin, e.detail.page, point);
+ });
+
+ document.body.addEventListener('navigate', e => {
+ const disposition = e.detail.newtab ?
+ PdfNavigator.WindowOpenDisposition.NEW_BACKGROUND_TAB :
+ PdfNavigator.WindowOpenDisposition.CURRENT_TAB;
+ this.navigator_.navigate(e.detail.uri, disposition);
+ });
+
+ document.body.addEventListener('dropdown-opened', e => {
+ if (e.detail == 'bookmarks') {
+ PDFMetrics.record(PDFMetrics.UserAction.OPEN_BOOKMARKS_PANEL);
+ }
+ });
+
+ /** @private {!ToolbarManager} */
+ this.toolbarManager_ =
+ new ToolbarManager(window, this.toolbar_, this.zoomToolbar_);
+
+ // Set up the ZoomManager.
+ /** @private {!ZoomManager} */
+ this.zoomManager_ = ZoomManager.create(
+ this.browserApi_.getZoomBehavior(), () => this.viewport_.getZoom(),
+ zoom => this.browserApi_.setZoom(zoom),
+ this.browserApi_.getInitialZoom());
+ this.viewport_.setZoomManager(this.zoomManager_);
+ this.browserApi_.addZoomEventListener(
+ zoom => this.zoomManager_.onBrowserZoomChange(zoom));
+
+ // Setup the keyboard event listener.
+ document.addEventListener(
+ 'keydown',
+ e => this.handleKeyEvent_(/** @type {!KeyboardEvent} */ (e)));
+ document.addEventListener('mousemove', e => this.handleMouseEvent_(e));
+ document.addEventListener('mouseout', e => this.handleMouseEvent_(e));
+ document.addEventListener(
+ 'contextmenu', e => this.handleContextMenuEvent_(e));
+
+ const tabId = this.browserApi_.getStreamInfo().tabId;
+ /** @private {!PdfNavigator} */
+ this.navigator_ = new PdfNavigator(
+ this.originalUrl_, this.viewport_, this.paramsParser_,
+ new NavigatorDelegate(tabId));
+
+ /** @private {!ViewportScroller} */
+ this.viewportScroller_ =
+ new ViewportScroller(this.viewport_, this.plugin_, window);
+
+ /** @private {!Array<!Bookmark>} */
+ this.bookmarks_;
+
+ /** @private {!Point} */
+ this.lastViewportPosition_;
+
+ /** @private {boolean} */
+ this.reverseZoomToolbar_;
+
+ /** @private {boolean} */
+ this.inPrintPreviewMode_;
+
+ /** @private {boolean} */
+ this.dark_;
+
+ /** @private {!DocumentDimensionsMessageData} */
+ this.documentDimensions_;
+
+ // Request translated strings.
+ chrome.resourcesPrivate.getStrings(
+ chrome.resourcesPrivate.Component.PDF,
+ strings => this.handleStrings_(strings));
+
+ // Listen for save commands from the browser.
+ if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) {
+ chrome.mimeHandlerPrivate.onSave.addListener(url => this.onSave_(url));
}
- });
-
- this.toolbarManager_ =
- new ToolbarManager(window, this.toolbar_, this.zoomToolbar_);
-
- // Set up the ZoomManager.
- this.zoomManager_ = ZoomManager.create(
- this.browserApi_.getZoomBehavior(), () => this.viewport_.getZoom(),
- zoom => this.browserApi_.setZoom(zoom),
- this.browserApi_.getInitialZoom());
- this.viewport_.setZoomManager(this.zoomManager_);
- this.browserApi_.addZoomEventListener(
- zoom => this.zoomManager_.onBrowserZoomChange(zoom));
-
- // Setup the keyboard event listener.
- document.addEventListener('keydown', e => this.handleKeyEvent_(e));
- document.addEventListener('mousemove', e => this.handleMouseEvent_(e));
- document.addEventListener('mouseout', e => this.handleMouseEvent_(e));
- document.addEventListener(
- 'contextmenu', e => this.handleContextMenuEvent_(e));
-
- const tabId = this.browserApi_.getStreamInfo().tabId;
- 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', strings => this.handleStrings_(strings));
-
- // Listen for save commands from the browser.
- if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) {
- chrome.mimeHandlerPrivate.onSave.addListener(url => this.onSave(url));
}
-}
-PDFViewer.prototype = {
/**
* Handle key events. These may come from the user directly or via the
* scripting API.
- *
- * @param {KeyboardEvent} e the event to handle.
+ * @param {!KeyboardEvent} e the event to handle.
* @private
*/
- handleKeyEvent_: function(e) {
+ handleKeyEvent_(e) {
const position = this.viewport_.position;
// Certain scroll events may be sent from outside of the extension.
const fromScriptingAPI = e.fromScriptingAPI;
@@ -357,7 +459,7 @@ PDFViewer.prototype = {
return;
}
- this.toolbarManager_.hideToolbarsAfterTimeout(e);
+ this.toolbarManager_.hideToolbarsAfterTimeout();
const pageUpHandler = () => {
// Go to the previous page if we are fit-to-page or fit-to-height.
@@ -366,8 +468,8 @@ PDFViewer.prototype = {
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
- position.y -= this.viewport.size.height;
- this.viewport.position = position;
+ position.y -= this.viewport_.size.height;
+ this.viewport_.position = position;
}
};
const pageDownHandler = () => {
@@ -377,8 +479,8 @@ PDFViewer.prototype = {
// Since we do the movement of the page.
e.preventDefault();
} else if (fromScriptingAPI) {
- position.y += this.viewport.size.height;
- this.viewport.position = position;
+ position.y += this.viewport_.size.height;
+ this.viewport_.position = position;
}
};
@@ -416,14 +518,14 @@ PDFViewer.prototype = {
e.preventDefault();
} else if (fromScriptingAPI) {
position.x -= Viewport.SCROLL_INCREMENT;
- this.viewport.position = position;
+ this.viewport_.position = position;
}
}
return;
case 38: // Up arrow key.
if (fromScriptingAPI) {
position.y -= Viewport.SCROLL_INCREMENT;
- this.viewport.position = position;
+ this.viewport_.position = position;
}
return;
case 39: // Right arrow key.
@@ -437,19 +539,19 @@ PDFViewer.prototype = {
e.preventDefault();
} else if (fromScriptingAPI) {
position.x += Viewport.SCROLL_INCREMENT;
- this.viewport.position = position;
+ this.viewport_.position = position;
}
}
return;
case 40: // Down arrow key.
if (fromScriptingAPI) {
position.y += Viewport.SCROLL_INCREMENT;
- this.viewport.position = position;
+ this.viewport_.position = position;
}
return;
case 65: // 'a' key.
if (e.ctrlKey || e.metaKey) {
- this.pluginController_.postMessage({type: 'selectAll'});
+ this.pluginController_.selectAll();
// Since we do selection ourselves.
e.preventDefault();
}
@@ -462,7 +564,7 @@ PDFViewer.prototype = {
return;
case 219: // Left bracket key.
if (e.ctrlKey) {
- this.rotateCounterclockwise();
+ this.rotateCounterclockwise_();
}
return;
case 220: // Backslash key.
@@ -472,7 +574,7 @@ PDFViewer.prototype = {
return;
case 221: // Right bracket key.
if (e.ctrlKey) {
- this.rotateClockwise();
+ this.rotateClockwise_();
}
return;
}
@@ -487,42 +589,49 @@ PDFViewer.prototype = {
this.toolbarManager_.showToolbars();
}
}
- },
+ }
- handleMouseEvent_: function(e) {
+ handleMouseEvent_(e) {
if (e.type == 'mousemove') {
this.toolbarManager_.handleMouseMove(e);
} else if (e.type == 'mouseout') {
this.toolbarManager_.hideToolbarsForMouseOut();
}
- },
+ }
- handleContextMenuEvent_: function(e) {
+ /**
+ * @param {!Event} e The context menu event
+ * @private
+ */
+ handleContextMenuEvent_(e) {
// Stop Chrome from popping up the context menu on long press. We need to
// make sure the start event did not have 2 touches because we don't want
// to block two finger tap opening the context menu. We check for
// firesTouchEvents in order to not block the context menu on right click.
- if (e.sourceCapabilities.firesTouchEvents &&
+ const capabilities =
+ /** @type {{ sourceCapabilities: Object }} */ (e).sourceCapabilities;
+ if (capabilities.firesTouchEvents &&
!this.gestureDetector_.wasTwoFingerTouch()) {
e.preventDefault();
}
- },
+ }
/**
* Handles the annotation mode being toggled on or off.
- *
* @param {!CustomEvent<{value: boolean}>} e
* @private
*/
- annotationModeToggled_: async function(e) {
+ async annotationModeToggled_(e) {
const annotationMode = e.detail.value;
if (annotationMode) {
// Enter annotation mode.
assert(this.currentController_ == this.pluginController_);
// TODO(dstockwell): set plugin read-only, begin transition
- this.updateProgress(0);
+ this.updateProgress_(0);
// TODO(dstockwell): handle save failure
- const result = await this.pluginController_.save(true);
+ const saveResult = await this.pluginController_.save(true);
+ // Data always exists when save is called with requireResult = true.
+ const result = /** @type {!RequiredSaveResult} */ (saveResult);
if (result.hasUnsavedChanges) {
assert(!loadTimeData.getBoolean('pdfFormSaveEnabled'));
try {
@@ -530,25 +639,26 @@ PDFViewer.prototype = {
} catch (e) {
// The user aborted entering annotation mode. Revert to the plugin.
this.toolbar_.annotationMode = false;
- this.updateProgress(100);
+ this.updateProgress_(100);
return;
}
}
PDFMetrics.record(PDFMetrics.UserAction.ENTER_ANNOTATION_MODE);
this.hasEnteredAnnotationMode_ = true;
// TODO(dstockwell): feed real progress data from the Ink component
- this.updateProgress(50);
+ this.updateProgress_(50);
await this.inkController_.load(result.fileName, result.dataToSave);
- this.inkController_.setAnnotationTool(this.toolbar_.annotationTool);
+ this.inkController_.setAnnotationTool(
+ assert(this.toolbar_.annotationTool));
this.currentController_ = this.inkController_;
this.pluginController_.unload();
- this.updateProgress(100);
+ this.updateProgress_(100);
} else {
// Exit annotation mode.
PDFMetrics.record(PDFMetrics.UserAction.EXIT_ANNOTATION_MODE);
assert(this.currentController_ == this.inkController_);
// TODO(dstockwell): set ink read-only, begin transition
- this.updateProgress(0);
+ this.updateProgress_(0);
// This runs separately to allow other consumers of `loaded` to queue
// up after this task.
this.loaded.then(() => {
@@ -556,36 +666,33 @@ PDFViewer.prototype = {
this.inkController_.unload();
});
// TODO(dstockwell): handle save failure
- const result = await this.inkController_.save(true);
+ const saveResult = await this.inkController_.save(true);
+ // Data always exists when save is called with requireResult = true.
+ const result = /** @type {!RequiredSaveResult} */ (saveResult);
await this.pluginController_.load(result.fileName, result.dataToSave);
// Ensure the plugin gets the initial viewport.
this.pluginController_.afterZoom();
}
- },
+ }
/**
* Exits annotation mode if active.
- *
* @return {Promise<void>}
*/
- exitAnnotationMode_: async function() {
+ async exitAnnotationMode_() {
if (!this.toolbar_.annotationMode) {
return;
}
this.toolbar_.toggleAnnotation();
await this.loaded;
- },
+ }
/**
* Request to change the viewport fitting type.
- *
- * @param {!CustomEvent<{
- * fittingType: FittingType,
- * userInitiated: boolean
- * }>} e
+ * @param {!CustomEvent<FitToChangedEvent>} e
* @private
*/
- fitToChanged_: function(e) {
+ fitToChanged_(e) {
if (e.detail.fittingType == FittingType.FIT_TO_PAGE) {
this.viewport_.fitToPage();
this.toolbarManager_.forceHideTopToolbar();
@@ -599,15 +706,14 @@ PDFViewer.prototype = {
if (e.detail.userInitiated) {
PDFMetrics.recordFitTo(e.detail.fittingType);
}
- },
+ }
/**
* Sends a 'documentLoaded' message to the PDFScriptingAPI if the document has
* finished loading.
- *
* @private
*/
- sendDocumentLoadedMessage_: function() {
+ sendDocumentLoadedMessage_() {
if (this.loadState_ == LoadState.LOADING) {
return;
}
@@ -616,17 +722,16 @@ PDFViewer.prototype = {
}
this.sendScriptingMessage_(
{type: 'documentLoaded', load_state: this.loadState_});
- },
+ }
/**
* Handle open pdf parameters. This function updates the viewport as per
* the parameters mentioned in the url while opening pdf. The order is
* important as later actions can override the effects of previous actions.
- *
* @param {Object} params The open params passed in the URL.
* @private
*/
- handleURLParams_: function(params) {
+ handleURLParams_(params) {
if (params.zoom) {
this.viewport_.setZoom(params.zoom);
}
@@ -654,32 +759,42 @@ PDFViewer.prototype = {
}
this.isUserInitiatedEvent_ = true;
}
- },
+ }
/**
* Moves the viewport to a point in a page. Called back after a
* 'transformPagePointReply' is returned from the plugin.
- *
* @param {string} origin Identifier for the caller for logging purposes.
* @param {number} page The index of the page to go to. zero-based.
- * @param {Object} message Message received from the plugin containing the
+ * @param {Point} message Message received from the plugin containing the
* x and y to navigate to in screen coordinates.
* @private
*/
- goToPageAndXY_: function(origin, page, message) {
+ goToPageAndXY_(origin, page, message) {
this.viewport_.goToPageAndXY(page, message.x, message.y);
if (origin == 'bookmark') {
PDFMetrics.record(PDFMetrics.UserAction.FOLLOW_BOOKMARK);
}
- },
+ }
/**
- * @return {Promise} Resolved when the load state reaches LOADED,
- * rejects on FAILED.
+ * @return {?Promise} Resolved when the load state reaches LOADED,
+ * rejects on FAILED. Returns null if no promise has been created, which
+ * is the case for initial load of the PDF.
*/
get loaded() {
- return this.loaded_.promise;
- },
+ return this.loaded_ ? this.loaded_.promise : null;
+ }
+
+ /** @return {!Viewport} The viewport. Used for testing. */
+ get viewport() {
+ return this.viewport_;
+ }
+
+ /** @return {!Array<!Bookmark>} The bookmarks. Used for testing. */
+ get bookmarks() {
+ return this.bookmarks_;
+ }
/**
* Updates the load state and triggers completion of the `loaded`
@@ -691,26 +806,29 @@ PDFViewer.prototype = {
if (this.loadState_ == loadState) {
return;
}
+ assert(
+ loadState == LoadState.LOADING || this.loadState_ == LoadState.LOADING);
+ this.loadState_ = loadState;
+ if (!this.initialLoadComplete_) {
+ this.initialLoadComplete_ = true;
+ return;
+ }
if (loadState == LoadState.SUCCESS) {
- assert(this.loadState_ == LoadState.LOADING);
this.loaded_.resolve();
} else if (loadState == LoadState.FAILED) {
- assert(this.loadState_ == LoadState.LOADING);
this.loaded_.reject();
} else {
- assert(loadState == LoadState.LOADING);
this.loaded_ = new PromiseResolver();
}
- this.loadState_ = loadState;
- },
+ }
/**
* Update the loading progress of the document in response to a progress
* message being received from the content controller.
- *
* @param {number} progress the progress as a percentage.
+ * @private
*/
- updateProgress: function(progress) {
+ updateProgress_(progress) {
if (this.toolbar_) {
this.toolbar_.loadProgress = progress;
}
@@ -743,28 +861,26 @@ PDFViewer.prototype = {
} else {
this.setLoadState_(LoadState.LOADING);
}
- },
+ }
/** @private */
- sendBackgroundColorForPrintPreview_: function() {
- this.pluginController_.postMessage({
- type: 'backgroundColorChanged',
- backgroundColor: this.dark_ ?
- PDFViewer.PRINT_PREVIEW_DARK_BACKGROUND_COLOR :
- PDFViewer.PRINT_PREVIEW_BACKGROUND_COLOR,
- });
- },
+ sendBackgroundColorForPrintPreview_() {
+ this.pluginController_.backgroundColorChanged(
+ this.dark_ ? PDFViewer.PRINT_PREVIEW_DARK_BACKGROUND_COLOR :
+ PDFViewer.PRINT_PREVIEW_BACKGROUND_COLOR);
+ }
/**
* Load a dictionary of translated strings into the UI. Used as a callback for
* chrome.resourcesPrivate.
- *
* @param {Object} strings Dictionary of translated strings
* @private
*/
- handleStrings_: function(strings) {
- document.documentElement.dir = strings.textdirection;
- document.documentElement.lang = strings.language;
+ handleStrings_(strings) {
+ const stringsDictionary =
+ /** @type {{ textdirection: string, language: string }} */ (strings);
+ document.documentElement.dir = stringsDictionary.textdirection;
+ document.documentElement.lang = stringsDictionary.language;
loadTimeData.data = strings;
const isNewPrintPreview = this.isPrintPreview_ &&
@@ -786,38 +902,34 @@ PDFViewer.prototype = {
if ($('form-warning')) {
$('form-warning').strings = strings;
}
- },
+ }
/**
* An event handler for handling password-submitted events. These are fired
* when an event is entered into the password screen.
- *
- * @param {Object} event a password-submitted event.
+ * @param {!CustomEvent<{password: string}>} event a password-submitted event.
* @private
*/
- onPasswordSubmitted_: function(event) {
- this.pluginController_.postMessage(
- {type: 'getPasswordComplete', password: event.detail.password});
- },
+ onPasswordSubmitted_(event) {
+ this.pluginController_.getPasswordComplete(event.detail.password);
+ }
/**
* A callback that sets |isUserInitiatedEvent_| to |userInitiated|.
- *
* @param {boolean} userInitiated The value to set |isUserInitiatedEvent_| to.
* @private
*/
- setUserInitiated_: function(userInitiated) {
+ setUserInitiated_(userInitiated) {
assert(this.isUserInitiatedEvent_ != userInitiated);
this.isUserInitiatedEvent_ = userInitiated;
- },
+ }
/**
* A callback that's called when an update to a pinch zoom is detected.
- *
* @param {!Object} e the pinch event.
* @private
*/
- onPinchUpdate_: function(e) {
+ onPinchUpdate_(e) {
// Throttle number of pinch events to one per frame.
if (!this.sentPinchEvent_) {
this.sentPinchEvent_ = true;
@@ -826,42 +938,39 @@ PDFViewer.prototype = {
this.viewport_.pinchZoom(e);
});
}
- },
+ }
/**
* A callback that's called when the end of a pinch zoom is detected.
- *
* @param {!Object} e the pinch event.
* @private
*/
- onPinchEnd_: function(e) {
+ onPinchEnd_(e) {
// Using rAF for pinch end prevents pinch updates scheduled by rAF getting
// sent after the pinch end.
window.requestAnimationFrame(() => {
this.viewport_.pinchZoomEnd(e);
});
- },
+ }
/**
* A callback that's called when the start of a pinch zoom is detected.
- *
* @param {!Object} e the pinch event.
* @private
*/
- onPinchStart_: function(e) {
+ onPinchStart_(e) {
// We also use rAF for pinch start, so that if there is a pinch end event
// scheduled by rAF, this pinch start will be sent after.
window.requestAnimationFrame(() => {
this.viewport_.pinchZoomStart(e);
});
- },
+ }
/**
* A callback that's called after the viewport changes.
- *
* @private
*/
- viewportChanged_: function() {
+ viewportChanged_() {
if (!this.documentDimensions_) {
return;
}
@@ -900,9 +1009,10 @@ PDFViewer.prototype = {
// TODO(raymes): Give pageIndicator_ the same API as toolbar_.
if (this.pageIndicator_) {
+ const lastIndex = this.pageIndicator_.index;
this.pageIndicator_.index = visiblePage;
if (this.documentDimensions_.pageDimensions.length > 1 &&
- hasScrollbars.vertical) {
+ hasScrollbars.vertical && lastIndex !== undefined) {
this.pageIndicator_.style.visibility = 'visible';
} else {
this.pageIndicator_.style.visibility = 'hidden';
@@ -921,16 +1031,15 @@ PDFViewer.prototype = {
viewportWidth: size.width,
viewportHeight: size.height
});
- },
+ }
/**
* Handle a scripting message from outside the extension (typically sent by
* PDFScriptingAPI in a page containing the extension) to interact with the
* plugin.
- *
- * @param {MessageObject} message the message to handle.
+ * @param {!MessageObject} message The message to handle.
*/
- handleScriptingMessage: function(message) {
+ handleScriptingMessage(message) {
if (this.parentWindow_ != message.source) {
this.parentWindow_ = message.source;
this.parentOrigin_ = message.origin;
@@ -953,30 +1062,38 @@ PDFViewer.prototype = {
switch (message.data.type.toString()) {
case 'getSelectedText':
+ this.pluginController_.getSelectedText();
+ break;
case 'print':
+ this.pluginController_.print();
+ break;
case 'selectAll':
- this.pluginController_.postMessage(message.data);
+ this.pluginController_.selectAll();
break;
}
- },
+ }
/**
* Handle scripting messages specific to print preview.
- *
- * @param {MessageObject} message the message to handle.
+ * @param {!MessageObject} message the message to handle.
* @return {boolean} true if the message was handled, false otherwise.
* @private
*/
- handlePrintPreviewScriptingMessage_: function(message) {
+ handlePrintPreviewScriptingMessage_(message) {
if (!this.isPrintPreview_) {
return false;
}
- switch (message.data.type.toString()) {
+ let messageData = message.data;
+ switch (messageData.type.toString()) {
case 'loadPreviewPage':
- this.pluginController_.postMessage(message.data);
+ messageData =
+ /** @type {{ url: string, index: number }} */ (messageData);
+ this.pluginController_.loadPreviewPage(
+ messageData.url, messageData.index);
return true;
case 'resetPrintPreviewMode':
+ messageData = /** @type {!PrintPreviewParams} */ (messageData);
this.setLoadState_(LoadState.LOADING);
if (!this.inPrintPreviewMode_) {
this.inPrintPreviewMode_ = true;
@@ -999,49 +1116,42 @@ PDFViewer.prototype = {
saveButton.parentNode.removeChild(saveButton);
}
- this.pageIndicator_.pageLabels = message.data.pageNumbers;
+ this.pageIndicator_.pageLabels = messageData.pageNumbers;
- this.pluginController_.postMessage({
- type: 'resetPrintPreviewMode',
- url: message.data.url,
- grayscale: message.data.grayscale,
- // If the PDF isn't modifiable we send 0 as the page count so that no
- // blank placeholder pages get appended to the PDF.
- pageCount:
- (message.data.modifiable ? message.data.pageNumbers.length : 0)
- });
+ this.pluginController_.resetPrintPreviewMode(messageData);
return true;
case 'sendKeyEvent':
- this.handleKeyEvent_(DeserializeKeyEvent(message.data.keyEvent));
+ this.handleKeyEvent_(/** @type {!KeyboardEvent} */ (DeserializeKeyEvent(
+ /** @type {{ keyEvent: Object }} */ (message.data).keyEvent)));
return true;
case 'hideToolbars':
this.toolbarManager_.resetKeyboardNavigationAndHideToolbars();
return true;
case 'darkModeChanged':
- this.dark_ = message.data.darkMode;
+ this.dark_ = /** @type {{darkMode: boolean}} */ (message.data).darkMode;
if (this.isPrintPreview_) {
this.sendBackgroundColorForPrintPreview_();
}
return true;
case 'scrollPosition':
const position = this.viewport_.position;
- position.y += message.data.y;
- position.x += message.data.x;
- this.viewport.position = position;
+ messageData = /** @type {{ x: number, y: number }} */ (message.data);
+ position.y += messageData.y;
+ position.x += messageData.x;
+ this.viewport_.position = position;
return true;
}
return false;
- },
+ }
/**
* Send a scripting message outside the extension (typically to
* PDFScriptingAPI in a page containing the extension).
- *
* @param {Object} message the message to send.
* @private
*/
- sendScriptingMessage_: function(message) {
+ sendScriptingMessage_(message) {
if (this.parentWindow_ && this.parentOrigin_) {
let targetOrigin;
// Only send data back to the embedder if it is from the same origin,
@@ -1057,34 +1167,73 @@ PDFViewer.prototype = {
}
this.parentWindow_.postMessage(message, targetOrigin);
}
- },
-
- /**
- * @type {Viewport} the viewport of the PDF viewer.
- */
- get viewport() {
- return this.viewport_;
- },
+ }
/**
- * Each bookmark is an Object containing a:
- * - title
- * - page (optional)
- * - array of children (themselves bookmarks)
- *
- * @type {Array} the top-level bookmarks of the PDF.
+ * @param {!CustomEvent<MessageData>} e
+ * @private
*/
- get bookmarks() {
- return this.bookmarks_;
- },
+ handlePluginMessage_(e) {
+ const data = e.detail;
+ switch (data.type.toString()) {
+ case 'beep':
+ this.handleBeep_();
+ return;
+ case 'documentDimensions':
+ this.setDocumentDimensions_(
+ /** @type {!DocumentDimensionsMessageData} */ (data));
+ return;
+ case 'getPassword':
+ this.handlePasswordRequest_();
+ return;
+ case 'getSelectedTextReply':
+ this.handleSelectedTextReply_(
+ /** @type {{ selectedText: string }} */ (data).selectedText);
+ return;
+ case 'loadProgress':
+ this.updateProgress_(
+ /** @type {{ progress: number }} */ (data).progress);
+ return;
+ case 'navigate':
+ const navigateData = /** @type {!NavigateMessageData} */ (data);
+ this.handleNavigate_(navigateData.url, navigateData.disposition);
+ return;
+ case 'navigateToDestination':
+ const destinationData = /** @type {!DestinationMessageData} */ (data);
+ this.handleNavigateToDestination_(
+ destinationData.page, destinationData.x, destinationData.y,
+ destinationData.zoom);
+ return;
+ case 'printPreviewLoaded':
+ this.handlePrintPreviewLoaded_();
+ return;
+ case 'metadata':
+ const metadata = /** @type {!MetadataMessageData} */ (data);
+ this.setDocumentMetadata_(
+ metadata.title, metadata.bookmarks, metadata.canSerializeDocument);
+ return;
+ case 'setIsSelecting':
+ this.setIsSelecting_(
+ /** @type {{ isSelecting: boolean }} */ (data).isSelecting);
+ return;
+ case 'getNamedDestinationReply':
+ this.paramsParser_.onNamedDestinationReceived(
+ /** @type {{ pageNumber: number }} */ (data).pageNumber);
+ return;
+ case 'formFocusChange':
+ this.isFormFieldFocused_ =
+ /** @type {{ focused: boolean }} */ (data).focused;
+ return;
+ }
+ assertNotReached('Unknown message type received: ' + data.type);
+ }
/**
* Sets document dimensions from the current controller.
- *
- * @param {{height: number, width: number, pageDimensions: Array}}
- * documentDimensions
+ * @param {!DocumentDimensionsMessageData} documentDimensions
+ * @private
*/
- setDocumentDimensions: function(documentDimensions) {
+ setDocumentDimensions_(documentDimensions) {
this.documentDimensions_ = documentDimensions;
this.isUserInitiatedEvent_ = false;
this.viewport_.setDocumentDimensions(this.documentDimensions_);
@@ -1098,20 +1247,22 @@ PDFViewer.prototype = {
if (this.toolbar_) {
this.toolbar_.docLength = this.documentDimensions_.pageDimensions.length;
}
- },
+ }
/**
* Handles a beep request from the current controller.
+ * @private
*/
- handleBeep: function() {
+ handleBeep_() {
// Beeps are annoying, so just track count for now.
this.beepCount_ += 1;
- },
+ }
/**
* Handles a password request from the current controller.
+ * @private
*/
- handlePasswordRequest: function() {
+ handlePasswordRequest_() {
// If the password screen isn't up, put it up. Otherwise we're
// responding to an incorrect password so deny it.
if (!this.passwordScreen_.active) {
@@ -1121,26 +1272,27 @@ PDFViewer.prototype = {
} else {
this.passwordScreen_.deny();
}
- },
+ }
/**
* Handles a selected text reply from the current controller.
* @param {string} selectedText
+ * @private
*/
- handleSelectedTextReply: function(selectedText) {
+ handleSelectedTextReply_(selectedText) {
this.sendScriptingMessage_({
type: 'getSelectedTextReply',
selectedText: selectedText,
});
- },
+ }
/**
* Handles a navigation request from the current controller.
- *
* @param {string} url
- * @param {string} disposition
+ * @param {!PdfNavigator.WindowOpenDisposition} disposition
+ * @private
*/
- handleNavigate: function(url, disposition) {
+ handleNavigate_(url, disposition) {
// If in print preview, always open a new tab.
if (this.isPrintPreview_) {
this.navigator_.navigate(
@@ -1148,24 +1300,48 @@ PDFViewer.prototype = {
} else {
this.navigator_.navigate(url, disposition);
}
- },
+ }
+
+ /**
+ * Handles an internal navigation request to a destination from the current
+ * controller.
+ *
+ * @param {number} page
+ * @param {number} x
+ * @param {number} y
+ * @param {number} zoom
+ * @private
+ */
+ handleNavigateToDestination_(page, x, y, zoom) {
+ if (zoom) {
+ this.viewport_.setZoom(zoom);
+ }
+
+ if (x || y) {
+ this.viewport_.goToPageAndXY(page, x ? x : 0, y ? y : 0);
+ } else {
+ this.viewport_.goToPage(page);
+ }
+ }
/**
* Handles a notification that print preview has loaded from the
* current controller.
+ * @private
*/
- handlePrintPreviewLoaded: function() {
+ handlePrintPreviewLoaded_() {
this.isPrintPreviewLoadingFinished_ = true;
this.sendDocumentLoadedMessage_();
- },
+ }
/**
* Sets document metadata from the current controller.
* @param {string} title
- * @param {Array} bookmarks
+ * @param {!Array<!Bookmark>} bookmarks
* @param {boolean} canSerializeDocument
+ * @private
*/
- setDocumentMetadata: function(title, bookmarks, canSerializeDocument) {
+ setDocumentMetadata_(title, bookmarks, canSerializeDocument) {
if (title) {
document.title = title;
} else {
@@ -1174,47 +1350,40 @@ PDFViewer.prototype = {
this.bookmarks_ = bookmarks;
if (this.toolbar_) {
this.toolbar_.docTitle = document.title;
- this.toolbar_.bookmarks = this.bookmarks;
+ this.toolbar_.bookmarks = this.bookmarks_;
}
this.canSerializeDocument_ = canSerializeDocument;
this.updateAnnotationAvailable_();
- },
+ }
/**
* Sets the is selecting flag from the current controller.
* @param {boolean} isSelecting
+ * @private
*/
- setIsSelecting: function(isSelecting) {
+ setIsSelecting_(isSelecting) {
this.viewportScroller_.setEnableScrolling(isSelecting);
- },
-
- /**
- * Sets the form field focused flag from the current controller.
- * @param {boolean} focused
- */
- setIsFormFieldFocused: function(focused) {
- this.isFormFieldFocused_ = focused;
- },
+ }
/**
* An event handler for when the browser tells the PDF Viewer to perform a
* save.
- *
* @param {string} streamUrl unique identifier for a PDF Viewer instance.
* @private
*/
- onSave: async function(streamUrl) {
+ async onSave_(streamUrl) {
if (streamUrl != this.browserApi_.getStreamInfo().streamUrl) {
return;
}
- this.save();
- },
+ this.save_();
+ }
/**
* Saves the current PDF document to disk.
+ * @private
*/
- save: async function() {
+ async save_() {
PDFMetrics.record(PDFMetrics.UserAction.SAVE);
if (this.hasEnteredAnnotationMode_) {
PDFMetrics.record(PDFMetrics.UserAction.SAVE_WITH_ANNOTATION);
@@ -1257,17 +1426,19 @@ PDFViewer.prototype = {
// Saving in Annotation mode is destructive: crbug.com/919364
this.exitAnnotationMode_();
- },
+ }
- print: async function() {
+ /** @private */
+ async print_() {
PDFMetrics.record(PDFMetrics.UserAction.PRINT);
await this.exitAnnotationMode_();
this.currentController_.print();
- },
+ }
/**
* Updates the toolbar's annotation available flag depending on current
* conditions.
+ * @private
*/
updateAnnotationAvailable_() {
if (!this.toolbar_) {
@@ -1284,408 +1455,67 @@ PDFViewer.prototype = {
annotationAvailable = false;
}
this.toolbar_.annotationAvailable = annotationAvailable;
- },
+ }
- rotateClockwise() {
+ /** @private */
+ rotateClockwise_() {
PDFMetrics.record(PDFMetrics.UserAction.ROTATE);
this.viewport_.rotateClockwise(1);
this.currentController_.rotateClockwise();
this.updateAnnotationAvailable_();
- },
+ }
- rotateCounterclockwise() {
+ /** @private */
+ rotateCounterclockwise_() {
PDFMetrics.record(PDFMetrics.UserAction.ROTATE);
this.viewport_.rotateClockwise(3);
this.currentController_.rotateCounterclockwise();
this.updateAnnotationAvailable_();
- },
-
- setHasUnsavedChanges: function() {
- // Warn the user if they attempt to close the window without saving.
- chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog(true);
- },
-
- /** @param {UndoState} state */
- setAnnotationUndoState(state) {
- this.toolbar_.canUndoAnnotation = state.canUndo;
- this.toolbar_.canRedoAnnotation = state.canRedo;
- },
-};
-
-/** @abstract */
-class ContentController {
- constructor() {}
-
- /**
- * A callback that's called before the zoom changes.
- */
- beforeZoom() {}
-
- /**
- * A callback that's called after the zoom changes.
- */
- afterZoom() {}
-
- /**
- * Handles a change to the viewport.
- */
- viewportChanged() {}
-
- /**
- * Rotates the document 90 degrees in the clockwise direction.
- * @abstract
- */
- rotateClockwise() {}
-
- /**
- * Rotates the document 90 degrees in the counter clockwise direction.
- * @abstract
- */
- rotateCounterclockwise() {}
-
- /**
- * Triggers printing of the current document.
- */
- print() {}
-
- /**
- * Undo an edit action.
- */
- undo() {}
-
- /**
- * Redo an edit action.
- */
- redo() {}
-
- /**
- * Requests that the current document be saved.
- * @param {boolean} requireResult whether a response is required, otherwise
- * the controller may save the document to disk internally.
- * @return {Promise<{fileName: string, dataToSave: ArrayBuffer}}
- * @abstract
- */
- save(requireResult) {}
-
- /**
- * Loads PDF document from `data` activates UI.
- * @param {string} fileName
- * @param {ArrayBuffer} data
- * @return {Promise<void>}
- * @abstract
- */
- load(fileName, data) {}
-
- /**
- * Unloads the current document and removes the UI.
- * @abstract
- */
- unload() {}
-}
-
-class InkController extends ContentController {
- /**
- * @param {PDFViewer} viewer
- * @param {Viewport} viewport
- */
- constructor(viewer, viewport) {
- super();
- this.viewer_ = viewer;
- this.viewport_ = viewport;
-
- /** @type {ViewerInkHost} */
- this.inkHost_ = null;
}
- /** @param {AnnotationTool} tool */
- setAnnotationTool(tool) {
- this.tool_ = tool;
- if (this.inkHost_) {
- this.inkHost_.setAnnotationTool(tool);
- }
- }
-
- /** @override */
- rotateClockwise() {
- // TODO(dstockwell): implement rotation
- }
-
- /** @override */
- rotateCounterclockwise() {
- // TODO(dstockwell): implement rotation
- }
-
- /** @override */
- viewportChanged() {
- this.inkHost_.viewportChanged();
- }
-
- /** @override */
- save(requireResult) {
- return this.inkHost_.saveDocument();
- }
-
- /** @override */
- undo() {
- this.inkHost_.undo();
- }
-
- /** @override */
- redo() {
- this.inkHost_.redo();
- }
-
- /** @override */
- load(filename, data) {
- if (!this.inkHost_) {
- this.inkHost_ = document.createElement('viewer-ink-host');
- $('content').appendChild(this.inkHost_);
- this.inkHost_.viewport = this.viewport_;
- this.inkHost_.addEventListener('stroke-added', e => {
- this.viewer_.setHasUnsavedChanges();
- });
- this.inkHost_.addEventListener('undo-state-changed', e => {
- this.viewer_.setAnnotationUndoState(e.detail);
- });
- }
- return this.inkHost_.load(filename, data);
- }
-
- /** @override */
- unload() {
- this.inkHost_.remove();
- this.inkHost_ = null;
- }
-}
-
-class PluginController extends ContentController {
/**
- * @param {HTMLEmbedElement} plugin
- * @param {PDFViewer} viewer
- * @param {Viewport} viewport
- */
- constructor(plugin, viewer, viewport) {
- super();
- this.plugin_ = plugin;
- this.viewer_ = viewer;
- this.viewport_ = viewport;
-
- /** @private {!Map<string, PromiseResolver>} */
- this.pendingTokens_ = new Map();
- this.plugin_.addEventListener(
- 'message', e => this.handlePluginMessage_(e), false);
- }
-
- /**
- * Notify the plugin to stop reacting to scroll events while zoom is taking
- * place to avoid flickering.
- * @override
- */
- beforeZoom() {
- this.postMessage({type: 'stopScrolling'});
-
- if (this.viewport_.pinchPhase == Viewport.PinchPhase.PINCH_START) {
- const position = this.viewport_.position;
- const zoom = this.viewport_.getZoom();
- const pinchPhase = this.viewport_.pinchPhase;
- this.postMessage({
- type: 'viewport',
- userInitiated: true,
- zoom: zoom,
- xOffset: position.x,
- yOffset: position.y,
- pinchPhase: pinchPhase
- });
- }
- }
-
- /**
- * Notify the plugin of the zoom change and to continue reacting to scroll
- * events.
- * @override
- */
- afterZoom() {
- const position = this.viewport_.position;
- 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;
-
- this.postMessage({
- type: 'viewport',
- userInitiated: this.viewer_.isUserInitiatedEvent_,
- zoom: zoom,
- xOffset: position.x,
- yOffset: position.y,
- pinchPhase: pinchPhase,
- pinchX: pinchCenter.x,
- pinchY: pinchCenter.y,
- pinchVectorX: pinchVector.x,
- pinchVectorY: pinchVector.y
- });
- }
-
- // TODO(dstockwell): this method should be private, add controller APIs that
- // map to all of the existing usage. crbug.com/913279
- /**
- * Post a message to the PPAPI plugin. Some messages will cause an async reply
- * to be received through handlePluginMessage_().
- *
- * @param {Object} message Message to post.
+ * @param {!CustomEvent<{canUndo: boolean, canRedo: boolean}>} e
+ * @private
*/
- postMessage(message) {
- this.plugin_.postMessage(message);
- }
-
- /** @override */
- rotateClockwise() {
- this.postMessage({type: 'rotateClockwise'});
- }
-
- /** @override */
- rotateCounterclockwise() {
- this.postMessage({type: 'rotateCounterclockwise'});
- }
-
- /** @override */
- print() {
- this.postMessage({type: 'print'});
- }
-
- /** @override */
- save(requireResult) {
- const resolver = new PromiseResolver();
- const newToken = createToken();
- this.pendingTokens_.set(newToken, resolver);
- this.postMessage({type: 'save', token: newToken, force: requireResult});
- return resolver.promise;
+ setAnnotationUndoState_(e) {
+ this.toolbar_.canUndoAnnotation = e.detail.canUndo;
+ this.toolbar_.canRedoAnnotation = e.detail.canRedo;
}
- /** @override */
- async load(fileName, data) {
- const url = URL.createObjectURL(new Blob([data]));
- this.plugin_.removeAttribute('headers');
- this.plugin_.setAttribute('stream-url', url);
- this.plugin_.style.display = 'block';
- try {
- await this.viewer_.loaded;
- } finally {
- URL.revokeObjectURL(url);
- }
- }
-
- /** @override */
- unload() {
- this.plugin_.style.display = 'none';
- }
-
- /**
- * An event handler for handling message events received from the plugin.
- *
- * @param {MessageObject} message a message event.
- * @private
- */
- handlePluginMessage_(message) {
- switch (message.data.type.toString()) {
- case 'beep':
- this.viewer_.handleBeep();
- break;
- case 'documentDimensions':
- this.viewer_.setDocumentDimensions(message.data);
- break;
- case 'email':
- const href = 'mailto:' + message.data.to + '?cc=' + message.data.cc +
- '&bcc=' + message.data.bcc + '&subject=' + message.data.subject +
- '&body=' + message.data.body;
- window.location.href = href;
- break;
- case 'getPassword':
- this.viewer_.handlePasswordRequest();
- break;
- case 'getSelectedTextReply':
- this.viewer_.handleSelectedTextReply(message.data.selectedText);
- break;
- case 'goToPage':
- this.viewport_.goToPage(message.data.page);
- break;
- case 'loadProgress':
- this.viewer_.updateProgress(message.data.progress);
- break;
- case 'navigate':
- this.viewer_.handleNavigate(message.data.url, message.data.disposition);
- break;
- case 'printPreviewLoaded':
- this.viewer_.handlePrintPreviewLoaded();
- break;
- case 'setScrollPosition':
- this.viewport_.scrollTo(/** @type {!PartialPoint} */ (message.data));
- break;
- case 'scrollBy':
- this.viewport_.scrollBy(/** @type {!Point} */ (message.data));
- break;
- case 'metadata':
- this.viewer_.setDocumentMetadata(
- message.data.title, message.data.bookmarks,
- message.data.canSerializeDocument);
- break;
- case 'setIsSelecting':
- this.viewer_.setIsSelecting(message.data.isSelecting);
- break;
- case 'getNamedDestinationReply':
- this.viewer_.paramsParser_.onNamedDestinationReceived(
- message.data.pageNumber);
- break;
- case 'formFocusChange':
- this.viewer_.setIsFormFieldFocused(message.data.focused);
- break;
- case 'saveData':
- this.saveData_(message.data);
- break;
- case 'consumeSaveToken':
- const resolver = this.pendingTokens_.get(message.data.token);
- assert(this.pendingTokens_.delete(message.data.token));
- resolver.resolve(null);
- break;
+ /** @private */
+ resetTrackers_() {
+ this.viewport_.resetTracker();
+ if (this.tracker_) {
+ this.tracker_.removeAll();
}
}
+}
- /**
- * Handles the pdf file buffer received from the plugin.
- *
- * @param {SaveDataMessageData} messageData data of the message event.
- * @private
- */
- saveData_(messageData) {
- assert(
- loadTimeData.getBoolean('pdfFormSaveEnabled') ||
- loadTimeData.getBoolean('pdfAnnotationsEnabled'));
-
- // Verify a token that was created by this instance is included to avoid
- // being spammed.
- const resolver = this.pendingTokens_.get(messageData.token);
- assert(this.pendingTokens_.delete(messageData.token));
+/**
+ * The height of the toolbar along the top of the page. The document will be
+ * shifted down by this much in the viewport.
+ */
+PDFViewer.MATERIAL_TOOLBAR_HEIGHT = 56;
- if (!messageData.dataToSave) {
- resolver.reject();
- return;
- }
+/**
+ * Minimum height for the material toolbar to show (px). Should match the media
+ * query in index-material.css. If the window is smaller than this at load,
+ * leave no space for the toolbar.
+ */
+PDFViewer.TOOLBAR_WINDOW_MIN_HEIGHT = 250;
- // Verify the file size and the first bytes to make sure it's a PDF. Cap at
- // 100 MB. This cap should be kept in sync with and is also enforced in
- // pdf/out_of_process_instance.cc.
- const MIN_FILE_SIZE = '%PDF1.0'.length;
- const MAX_FILE_SIZE = 100 * 1000 * 1000;
+/**
+ * The background color used for print preview (--google-grey-refresh-300).
+ */
+PDFViewer.PRINT_PREVIEW_BACKGROUND_COLOR = '0xFFDADCE0';
- const buffer = messageData.dataToSave;
- const bufView = new Uint8Array(buffer);
- assert(
- bufView.length <= MAX_FILE_SIZE,
- `File too large to be saved: ${bufView.length} bytes.`);
- assert(bufView.length >= MIN_FILE_SIZE);
- assert(
- String.fromCharCode(bufView[0], bufView[1], bufView[2], bufView[3]) ==
- '%PDF');
+/**
+ * The background color used for print preview when dark mode is enabled
+ * (--google-grey-refresh-700).
+ */
+PDFViewer.PRINT_PREVIEW_DARK_BACKGROUND_COLOR = '0xFF5F6368';
- resolver.resolve(messageData);
- }
-}
+/**
+ * The background color used for the regular viewer.
+ */
+PDFViewer.BACKGROUND_COLOR = '0xFF525659';
diff --git a/chromium/chrome/browser/resources/pdf/toolbar_manager.js b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
index 255bc3394f1..8a2b06c135c 100644
--- a/chromium/chrome/browser/resources/pdf/toolbar_manager.js
+++ b/chromium/chrome/browser/resources/pdf/toolbar_manager.js
@@ -20,10 +20,8 @@ const TOP_TOOLBAR_REVEAL_DISTANCE = 100;
const SIDE_TOOLBAR_REVEAL_DISTANCE_RIGHT = 150;
const SIDE_TOOLBAR_REVEAL_DISTANCE_BOTTOM = 250;
-
-
/**
- * @param {MouseEvent} e Event to test.
+ * @param {!MouseEvent} e Event to test.
* @return {boolean} True if the mouse is close to the top of the screen.
*/
function isMouseNearTopToolbar(e) {
@@ -31,7 +29,7 @@ function isMouseNearTopToolbar(e) {
}
/**
- * @param {MouseEvent} e Event to test.
+ * @param {!MouseEvent} e Event to test.
* @param {Window} window Window to test against.
* @param {boolean} reverse Whether the side toolbar is reversed.
* @return {boolean} True if the mouse is close to the bottom-right of the
@@ -47,47 +45,60 @@ function isMouseNearSideToolbar(e, window, reverse) {
return atSide && atBottom;
}
-/**
- * Constructs a Toolbar Manager, responsible for co-ordinating between multiple
- * toolbar elements.
- *
- * @param {Object} window The window containing the UI.
- * @param {Object} toolbar The top toolbar element.
- * @param {Object} zoomToolbar The zoom toolbar element.
- * @constructor
- */
-function ToolbarManager(window, toolbar, zoomToolbar) {
- this.window_ = window;
- this.toolbar_ = toolbar;
- this.zoomToolbar_ = zoomToolbar;
+/** Responsible for co-ordinating between multiple toolbar elements. */
+class ToolbarManager {
+ /**
+ * @param {!Window} window The window containing the UI.
+ * @param {?ViewerPdfToolbarElement} toolbar
+ * @param {!ViewerZoomToolbarElement} zoomToolbar
+ */
+ constructor(window, toolbar, zoomToolbar) {
+ /** @private {!Window} */
+ this.window_ = window;
- this.toolbarTimeout_ = null;
- this.isMouseNearTopToolbar_ = false;
- this.isMouseNearSideToolbar_ = false;
+ /** @private {?ViewerPdfToolbarElement} */
+ this.toolbar_ = toolbar;
- this.sideToolbarAllowedOnly_ = false;
- this.sideToolbarAllowedOnlyTimer_ = null;
+ /** @private {!ViewerZoomToolbarElement} */
+ this.zoomToolbar_ = zoomToolbar;
- this.keyboardNavigationActive = false;
+ /** @private {?number} */
+ this.toolbarTimeout_ = null;
- this.lastMovementTimestamp = null;
+ /** @private {boolean} */
+ this.isMouseNearTopToolbar_ = false;
- this.reverseSideToolbar_ = false;
+ /** @private {boolean} */
+ this.isMouseNearSideToolbar_ = false;
- this.window_.addEventListener('resize', this.resizeDropdowns_.bind(this));
- this.resizeDropdowns_();
+ /** @private {boolean} */
+ this.sideToolbarAllowedOnly_ = false;
- if (zoomToolbar.isPrintPreview()) {
- this.zoomToolbar_.addEventListener('keyboard-navigation-active', e => {
- this.keyboardNavigationActive = e.detail;
- });
- }
-}
+ /** @private {?number} */
+ this.sideToolbarAllowedOnlyTimer_ = null;
+
+ /** @private {boolean} */
+ this.keyboardNavigationActive = false;
+
+ /** @private {?number} */
+ this.lastMovementTimestamp = null;
-ToolbarManager.prototype = {
+ /** @private {boolean} */
+ this.reverseSideToolbar_ = false;
+
+ this.window_.addEventListener('resize', this.resizeDropdowns_.bind(this));
+ this.resizeDropdowns_();
+
+ if (zoomToolbar.isPrintPreview()) {
+ this.zoomToolbar_.addEventListener('keyboard-navigation-active', e => {
+ this.keyboardNavigationActive = e.detail;
+ });
+ }
+ }
- handleMouseMove: function(e) {
- this.isMouseNearTopToolbar_ = this.toolbar_ && isMouseNearTopToolbar(e);
+ /** @param {!MouseEvent} e */
+ handleMouseMove(e) {
+ this.isMouseNearTopToolbar_ = !!this.toolbar_ && isMouseNearTopToolbar(e);
this.isMouseNearSideToolbar_ =
isMouseNearSideToolbar(e, this.window_, this.reverseSideToolbar_);
@@ -123,17 +134,16 @@ ToolbarManager.prototype = {
}
}
this.hideToolbarsAfterTimeout();
- },
+ }
/**
* Whether a mousemove event is high enough velocity to reveal the toolbars.
- *
- * @param {MouseEvent} e Event to test.
+ * @param {!MouseEvent} e Event to test.
* @return {boolean} true if the event is a high velocity mousemove, false
* otherwise.
* @private
*/
- isHighVelocityMouseMove_: function(e) {
+ isHighVelocityMouseMove_(e) {
if (e.type == 'mousemove') {
if (this.lastMovementTimestamp == null) {
this.lastMovementTimestamp = this.getCurrentTimestamp_();
@@ -150,54 +160,51 @@ ToolbarManager.prototype = {
}
}
return false;
- },
+ }
/**
* Wrapper around Date.now() to make it easily replaceable for testing.
- *
* @return {number}
* @private
*/
- getCurrentTimestamp_: function() {
+ getCurrentTimestamp_() {
return Date.now();
- },
+ }
- /**
- * Display both UI toolbars.
- */
- showToolbars: function() {
+ /** Display both UI toolbars. */
+ showToolbars() {
if (this.toolbar_) {
this.toolbar_.show();
}
this.zoomToolbar_.show();
- },
+ }
/**
* Show toolbars and mark that navigation is being performed with
* tab/shift-tab. This disables toolbar hiding until the mouse is moved or
* escape is pressed.
*/
- showToolbarsForKeyboardNavigation: function() {
+ showToolbarsForKeyboardNavigation() {
this.keyboardNavigationActive = true;
this.showToolbars();
- },
+ }
/**
* Hide toolbars after a delay, regardless of the position of the mouse.
* Intended to be called when the mouse has moved out of the parent window.
*/
- hideToolbarsForMouseOut: function() {
+ hideToolbarsForMouseOut() {
this.isMouseNearTopToolbar_ = false;
this.isMouseNearSideToolbar_ = false;
this.hideToolbarsAfterTimeout();
- },
+ }
/**
* Check if the toolbars are able to be closed, and close them if they are.
* Toolbars may be kept open based on mouse/keyboard activity and active
* elements.
*/
- hideToolbarsIfAllowed: function() {
+ hideToolbarsIfAllowed() {
if (this.isMouseNearSideToolbar_ || this.isMouseNearTopToolbar_) {
return;
}
@@ -221,47 +228,44 @@ ToolbarManager.prototype = {
this.toolbar_.hide();
}
this.zoomToolbar_.hide();
- },
+ }
- /**
- * Hide the toolbar after the HIDE_TIMEOUT has elapsed.
- */
- hideToolbarsAfterTimeout: function() {
+ /** Hide the toolbars after the HIDE_TIMEOUT has elapsed. */
+ hideToolbarsAfterTimeout() {
if (this.toolbarTimeout_) {
this.window_.clearTimeout(this.toolbarTimeout_);
}
this.toolbarTimeout_ = this.window_.setTimeout(
this.hideToolbarsIfAllowed.bind(this), HIDE_TIMEOUT);
- },
+ }
/**
* Hide the 'topmost' layer of toolbars. Hides any dropdowns that are open, or
* hides the basic toolbars otherwise.
*/
- hideSingleToolbarLayer: function() {
+ hideSingleToolbarLayer() {
if (!this.toolbar_ || !this.toolbar_.hideDropdowns()) {
this.keyboardNavigationActive = false;
this.hideToolbarsIfAllowed();
}
- },
+ }
/**
* Clears the keyboard navigation state and hides the toolbars after a delay.
*/
- resetKeyboardNavigationAndHideToolbars: function() {
+ resetKeyboardNavigationAndHideToolbars() {
this.keyboardNavigationActive = false;
this.hideToolbarsAfterTimeout();
- },
+ }
/**
* Hide the top toolbar and keep it hidden until both:
* - The mouse is moved away from the right side of the screen
* - 1 second has passed.
- *
* The top toolbar can be immediately re-opened by moving the mouse to the top
* of the screen.
*/
- forceHideTopToolbar: function() {
+ forceHideTopToolbar() {
if (!this.toolbar_) {
return;
}
@@ -270,20 +274,19 @@ ToolbarManager.prototype = {
this.sideToolbarAllowedOnlyTimer_ = this.window_.setTimeout(() => {
this.sideToolbarAllowedOnlyTimer_ = null;
}, FORCE_HIDE_TIMEOUT);
- },
+ }
/** Reverse the position of the side toolbar. */
- reverseSideToolbar: function() {
+ reverseSideToolbar() {
this.reverseSideToolbar_ = true;
- },
+ }
/**
* Updates the size of toolbar dropdowns based on the positions of the rest of
* the UI.
- *
* @private
*/
- resizeDropdowns_: function() {
+ resizeDropdowns_() {
if (!this.toolbar_) {
return;
}
@@ -291,4 +294,4 @@ ToolbarManager.prototype = {
this.window_.innerHeight - this.zoomToolbar_.clientHeight;
this.toolbar_.setDropdownLowerBound(lowerBound);
}
-};
+}
diff --git a/chromium/chrome/browser/resources/pdf/viewport.js b/chromium/chrome/browser/resources/pdf/viewport.js
index 480664c014c..17986ae5d81 100644
--- a/chromium/chrome/browser/resources/pdf/viewport.js
+++ b/chromium/chrome/browser/resources/pdf/viewport.js
@@ -6,14 +6,21 @@
* @typedef {{
* width: number,
* height: number,
+ * layoutOptions: (!LayoutOptions|undefined),
* pageDimensions: Array<ViewportRect>,
* }}
*/
let DocumentDimensions;
+/** @typedef {{defaultPageOrientation: number}} */
+let LayoutOptions;
+
/** @typedef {{x: number, y: number}} */
let Point;
+/** @typedef {{x: (number|undefined), y: (number|undefined)}} */
+let PartialPoint;
+
/** @typedef {{width: number, height: number}} */
let Size;
@@ -279,6 +286,15 @@ class Viewport {
}
/**
+ * @return {!LayoutOptions|undefined} A dictionary carrying layout options
+ * from the plugin.
+ */
+ getLayoutOptions() {
+ return this.documentDimensions_ ? this.documentDimensions_.layoutOptions :
+ undefined;
+ }
+
+ /**
* @return {!ViewportRect} ViewportRect for the viewport given current zoom.
* @private
*/
@@ -605,7 +621,7 @@ class Viewport {
const bottom =
this.pageDimensions_[page].y + this.pageDimensions_[page].height;
- if (top <= y && bottom > y) {
+ if (top <= y && y <= bottom) {
return page;
}
@@ -1166,7 +1182,9 @@ class Viewport {
this.fittingType_ == FittingType.FIT_TO_HEIGHT);
}
- /** @param {!Point} point The position to which to scroll the viewport. */
+ /**
+ * @param {!PartialPoint} point The position to which to scroll the viewport.
+ */
scrollTo(point) {
let changed = false;
const newPosition = this.position;
diff --git a/chromium/chrome/browser/resources/pdf/viewport_scroller.js b/chromium/chrome/browser/resources/pdf/viewport_scroller.js
index bb8c187d478..ca16c9cf7d2 100644
--- a/chromium/chrome/browser/resources/pdf/viewport_scroller.js
+++ b/chromium/chrome/browser/resources/pdf/viewport_scroller.js
@@ -5,75 +5,61 @@
'use strict';
/**
- * The period of time in milliseconds to wait between updating the viewport
- * position by the scroll velocity.
- *
- * @private
- */
-ViewportScroller.DRAG_TIMER_INTERVAL_MS_ = 100;
-
-/**
- * The maximum drag scroll distance per DRAG_TIMER_INTERVAL in pixels.
- *
- * @private
- */
-ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_ = 100;
-
-/**
* Creates a new ViewportScroller.
* A ViewportScroller scrolls the page in response to drag selection with the
* mouse.
*
- * @param {Object} viewport The viewport info of the page.
- * @param {Object} plugin The PDF plugin element.
- * @param {Object} window The window containing the viewer.
- * @constructor
*/
-function ViewportScroller(viewport, plugin, window) {
- this.viewport_ = viewport;
- this.plugin_ = plugin;
- this.window_ = window;
- this.mousemoveCallback_ = null;
- this.timerId_ = null;
- this.scrollVelocity_ = null;
- this.lastFrameTime_ = 0;
-}
+class ViewportScroller {
+ /**
+ * @param {Object} viewport The viewport info of the page.
+ * @param {Object} plugin The PDF plugin element.
+ * @param {Object} window The window containing the viewer.
+ */
+ constructor(viewport, plugin, window) {
+ this.viewport_ = viewport;
+ this.plugin_ = plugin;
+ this.window_ = window;
+ this.mousemoveCallback_ = null;
+ this.timerId_ = null;
+ this.scrollVelocity_ = null;
+ this.lastFrameTime_ = 0;
+ }
-ViewportScroller.prototype = {
/**
* Start scrolling the page by |scrollVelocity_| every
* |DRAG_TIMER_INTERVAL_MS_|.
*
* @private
*/
- startDragScrollTimer_: function() {
+ startDragScrollTimer_() {
if (this.timerId_ === null) {
this.timerId_ = this.window_.setInterval(
this.dragScrollPage_.bind(this),
ViewportScroller.DRAG_TIMER_INTERVAL_MS_);
this.lastFrameTime_ = Date.now();
}
- },
+ }
/**
* Stops the drag scroll timer if it is active.
*
* @private
*/
- stopDragScrollTimer_: function() {
+ stopDragScrollTimer_() {
if (this.timerId_ !== null) {
this.window_.clearInterval(this.timerId_);
this.timerId_ = null;
this.lastFrameTime_ = 0;
}
- },
+ }
/**
* Scrolls the viewport by the current scroll velocity.
*
* @private
*/
- dragScrollPage_: function() {
+ dragScrollPage_() {
const position = this.viewport_.position;
const currentFrameTime = Date.now();
const timeAdjustment = (currentFrameTime - this.lastFrameTime_) /
@@ -82,7 +68,7 @@ ViewportScroller.prototype = {
position.x += (this.scrollVelocity_.x * timeAdjustment);
this.viewport_.position = position;
this.lastFrameTime_ = currentFrameTime;
- },
+ }
/**
* Calculate the velocity to scroll while dragging using the distance of the
@@ -92,7 +78,7 @@ ViewportScroller.prototype = {
* @return {Object} Object with x and y direction scroll velocity.
* @private
*/
- calculateVelocity_: function(event) {
+ calculateVelocity_(event) {
const x =
Math.min(
Math.max(
@@ -106,7 +92,7 @@ ViewportScroller.prototype = {
ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_) *
Math.sign(event.offsetY);
return {x: x, y: y};
- },
+ }
/**
* Handles mousemove events. It updates the scroll velocity and starts and
@@ -115,14 +101,14 @@ ViewportScroller.prototype = {
* @param {Object} event The mousemove event.
* @private
*/
- onMousemove_: function(event) {
+ onMousemove_(event) {
this.scrollVelocity_ = this.calculateVelocity_(event);
if (!this.scrollVelocity_.x && !this.scrollVelocity_.y) {
this.stopDragScrollTimer_();
} else if (!this.timerId_) {
this.startDragScrollTimer_();
}
- },
+ }
/**
* Sets whether to scroll the viewport when the mouse is outside the
@@ -130,7 +116,7 @@ ViewportScroller.prototype = {
*
* @param {boolean} isSelecting Represents selection status.
*/
- setEnableScrolling: function(isSelecting) {
+ setEnableScrolling(isSelecting) {
if (isSelecting) {
if (!this.mousemoveCallback_) {
this.mousemoveCallback_ = this.onMousemove_.bind(this);
@@ -145,4 +131,19 @@ ViewportScroller.prototype = {
}
}
}
-};
+}
+
+/**
+ * The period of time in milliseconds to wait between updating the viewport
+ * position by the scroll velocity.
+ *
+ * @private
+ */
+ViewportScroller.DRAG_TIMER_INTERVAL_MS_ = 100;
+
+/**
+ * The maximum drag scroll distance per DRAG_TIMER_INTERVAL in pixels.
+ *
+ * @private
+ */
+ViewportScroller.MAX_DRAG_SCROLL_DISTANCE_ = 100;
diff --git a/chromium/chrome/browser/resources/print_preview/BUILD.gn b/chromium/chrome/browser/resources/print_preview/BUILD.gn
index fe72fb197fb..0bb1822b6fe 100644
--- a/chromium/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/BUILD.gn
@@ -77,9 +77,9 @@ js_type_check("print_preview_resources") {
js_library("print_preview_utils") {
deps = [
":dark_mode_behavior",
+ "//third_party/polymer/v1_0/components-chromium/iron-iconset-svg:iron-iconset-svg-extracted",
"//ui/webui/resources/js:util",
]
- externs_list = [ "$externs_path/pending.js" ]
}
js_library("metrics") {
@@ -127,6 +127,7 @@ js_library("cloud_print_interface_native") {
js_library("native_layer") {
deps = [
"data:destination",
+ "data:destination_match",
"data:measurement_system",
"//ui/webui/resources/js:cr",
]
diff --git a/chromium/chrome/browser/resources/print_preview/data/BUILD.gn b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
index 5ab503b223e..7f04cc61c7b 100644
--- a/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
@@ -19,6 +19,7 @@ js_type_check("closure_compile") {
":measurement_system",
":model",
":printable_area",
+ ":scaling",
":size",
":state",
]
@@ -50,6 +51,7 @@ js_library("invitation_store") {
js_library("local_parsers") {
deps = [
":destination",
+ ":destination_match",
"..:native_layer",
"//ui/webui/resources/js:cr",
]
@@ -58,7 +60,6 @@ js_library("local_parsers") {
js_library("destination_match") {
deps = [
":destination",
- "..:native_layer",
"//ui/webui/resources/js:cr",
]
}
@@ -111,8 +112,10 @@ js_library("measurement_system") {
js_library("model") {
deps = [
":destination",
+ ":destination_match",
":document_info",
":margins",
+ ":scaling",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:promise_resolver",
]
@@ -126,6 +129,12 @@ js_library("printable_area") {
]
}
+js_library("scaling") {
+ deps = [
+ "//ui/webui/resources/js:cr",
+ ]
+}
+
js_library("size") {
deps = [
"//ui/webui/resources/js:cr",
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.js b/chromium/chrome/browser/resources/print_preview/data/destination.js
index 403becbf6d1..761891d5c01 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination.js
@@ -95,6 +95,17 @@ cr.define('print_preview', function() {
let VendorCapabilitySelectOption;
/**
+ * Same as cloud_devices::printer::TypedValueVendorCapability::ValueType.
+ * @enum {string}
+ */
+ const VendorCapabilityValueType = {
+ BOOLEAN: 'BOOLEAN',
+ FLOAT: 'FLOAT',
+ INTEGER: 'INTEGER',
+ STRING: 'STRING',
+ };
+
+ /**
* Specifies a custom vendor capability.
* @typedef {{
* id: (string),
@@ -106,6 +117,7 @@ cr.define('print_preview', function() {
* }|undefined),
* typed_value_cap: ({
* default: (number | string | boolean | undefined),
+ * value_type: (print_preview.VendorCapabilityValueType | undefined),
* }|undefined),
* range_cap: ({
* default: (number),
@@ -219,14 +231,31 @@ cr.define('print_preview', function() {
};
/**
+ * Enumeration of background graphics printing mode restrictions used by
+ * Chromium.
+ * This has to coincide with |printing::BackgroundGraphicsModeRestriction| as
+ * defined in printing/backend/printing_restrictions.h
+ * @enum {number}
+ */
+ const BackgroundGraphicsModeRestriction = {
+ UNSET: 0,
+ ENABLED: 1,
+ DISABLED: 2,
+ };
+
+ /**
* Policies affecting a destination.
* @typedef {{
* allowedColorModes: ?print_preview.ColorModeRestriction,
* allowedDuplexModes: ?print_preview.DuplexModeRestriction,
* allowedPinMode: ?print_preview.PinModeRestriction,
+ * allowedBackgroundGraphicsMode:
+ * ?print_preview.BackgroundGraphicsModeRestriction,
* defaultColorMode: ?print_preview.ColorModeRestriction,
* defaultDuplexMode: ?print_preview.DuplexModeRestriction,
* defaultPinMode: ?print_preview.PinModeRestriction,
+ * defaultBackgroundGraphicsMode:
+ * ?print_preview.BackgroundGraphicsModeRestriction,
* }}
*/
let Policies;
@@ -821,6 +850,16 @@ cr.define('print_preview', function() {
this.policies.allowedPinModes :
null;
}
+
+ /**
+ * @return {?print_preview.BackgroundGraphicsModeRestriction} Background
+ * graphics mode allowed by policy.
+ */
+ get backgroundGraphicsPolicy() {
+ return this.policies && this.policies.allowedBackgroundGraphicsModes ?
+ this.policies.allowedBackgroundGraphicsModes :
+ null;
+ }
// </if>
/**
@@ -867,6 +906,14 @@ cr.define('print_preview', function() {
get defaultPinPolicy() {
return this.policies && this.policies.defaultPinMode;
}
+
+ /**
+ * @return {?print_preview.BackgroundGraphicsModeRestriction} Value of
+ * default background graphics setting given by policy.
+ */
+ get defaultBackgroundGraphicsPolicy() {
+ return this.policies && this.policies.defaultBackgroundGraphicsMode;
+ }
// </if>
/**
@@ -966,9 +1013,11 @@ cr.define('print_preview', function() {
makeRecentDestination: makeRecentDestination,
RecentDestination: RecentDestination,
VendorCapabilitySelectOption: VendorCapabilitySelectOption,
+ VendorCapabilityValueType: VendorCapabilityValueType,
VendorCapability: VendorCapability,
// <if expr="chromeos">
+ BackgroundGraphicsModeRestriction: BackgroundGraphicsModeRestriction,
ColorModeRestriction: ColorModeRestriction,
DuplexModeRestriction: DuplexModeRestriction,
PinModeRestriction: PinModeRestriction,
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination_match.html b/chromium/chrome/browser/resources/print_preview/data/destination_match.html
index 35c9a62fc62..288ce95f4ce 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination_match.html
+++ b/chromium/chrome/browser/resources/print_preview/data/destination_match.html
@@ -1,5 +1,4 @@
<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="../native_layer.html">
<link rel="import" href="destination.html">
<script src="destination_match.js"></script>
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination_match.js b/chromium/chrome/browser/resources/print_preview/data/destination_match.js
index 9e3e9307f93..c147e002611 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination_match.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination_match.js
@@ -5,6 +5,19 @@
cr.define('print_preview', function() {
'use strict';
/**
+ * Printer types for capabilities and printer list requests.
+ * Must match PrinterType in printing/print_job_constants.h
+ * @enum {number}
+ */
+ const PrinterType = {
+ PRIVET_PRINTER: 0,
+ EXTENSION_PRINTER: 1,
+ PDF_PRINTER: 2,
+ LOCAL_PRINTER: 3,
+ CLOUD_PRINTER: 4
+ };
+
+ /**
* Converts DestinationOrigin to PrinterType.
* @param {!print_preview.DestinationOrigin} origin The printer's
* destination origin.
@@ -25,6 +38,19 @@ cr.define('print_preview', function() {
return print_preview.PrinterType.CLOUD_PRINTER;
};
+ /**
+ * @param {!print_preview.Destination} destination The destination to figure
+ * out the printer type of.
+ * @return {!print_preview.PrinterType} Map the destination to a PrinterType.
+ */
+ function getPrinterTypeForDestination(destination) {
+ if (destination.id ==
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {
+ return print_preview.PrinterType.PDF_PRINTER;
+ }
+ return print_preview.originToType(destination.origin);
+ }
+
class DestinationMatch {
/**
* A set of key parameters describing a destination used to determine
@@ -116,5 +142,10 @@ cr.define('print_preview', function() {
}
// Export
- return {originToType: originToType, DestinationMatch: DestinationMatch};
+ return {
+ DestinationMatch: DestinationMatch,
+ PrinterType: PrinterType,
+ getPrinterTypeForDestination: getPrinterTypeForDestination,
+ originToType: originToType,
+ };
});
diff --git a/chromium/chrome/browser/resources/print_preview/data/document_info.js b/chromium/chrome/browser/resources/print_preview/data/document_info.js
index 67ce1c952af..d85124d3a13 100644
--- a/chromium/chrome/browser/resources/print_preview/data/document_info.js
+++ b/chromium/chrome/browser/resources/print_preview/data/document_info.js
@@ -9,6 +9,7 @@ cr.exportPath('print_preview');
* hasCssMediaStyles: boolean,
* hasSelection: boolean,
* isModifiable: boolean,
+ * isPdf: boolean,
* isScalingDisabled: boolean,
* fitToPageScaling: number,
* pageCount: number,
@@ -48,6 +49,7 @@ Polymer({
hasCssMediaStyles: false,
hasSelection: false,
isModifiable: true,
+ isPdf: false,
isScalingDisabled: false,
fitToPageScaling: 100,
pageCount: 0,
@@ -113,13 +115,16 @@ Polymer({
/**
* Initializes the state of the data model.
* @param {boolean} isModifiable Whether the document is modifiable.
+ * @param {boolean} isPdf Whether the document is PDF.
* @param {string} title Title of the document.
* @param {boolean} hasSelection Whether the document has user-selected
* content.
*/
- init: function(isModifiable, title, hasSelection) {
+ init: function(isModifiable, isPdf, title, hasSelection) {
this.isInitialized_ = true;
this.set('documentSettings.isModifiable', isModifiable);
+ // TODO(crbug.com/702995): Remove once Flash is deprecated.
+ this.set('documentSettings.isPdf', isPdf);
this.set('documentSettings.title', title);
this.set('documentSettings.hasSelection', hasSelection);
},
@@ -154,7 +159,7 @@ Polymer({
Math.round(pageLayout.marginTop), Math.round(pageLayout.marginRight),
Math.round(pageLayout.marginBottom), Math.round(pageLayout.marginLeft));
- const o = print_preview.ticket_items.CustomMarginsOrientation;
+ const o = print_preview.CustomMarginsOrientation;
const pageSize = new print_preview.Size(
pageLayout.contentWidth + margins.get(o.LEFT) + margins.get(o.RIGHT),
pageLayout.contentHeight + margins.get(o.TOP) + margins.get(o.BOTTOM));
diff --git a/chromium/chrome/browser/resources/print_preview/data/local_parsers.html b/chromium/chrome/browser/resources/print_preview/data/local_parsers.html
index b6fe90e29d7..fed4e851ed9 100644
--- a/chromium/chrome/browser/resources/print_preview/data/local_parsers.html
+++ b/chromium/chrome/browser/resources/print_preview/data/local_parsers.html
@@ -1,5 +1,6 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="../native_layer.html">
<link rel="import" href="destination.html">
+<link rel="import" href="destination_match.html">
<script src="local_parsers.js"></script>
diff --git a/chromium/chrome/browser/resources/print_preview/data/margins.js b/chromium/chrome/browser/resources/print_preview/data/margins.js
index 3facd5a82cd..ce38eb65947 100644
--- a/chromium/chrome/browser/resources/print_preview/data/margins.js
+++ b/chromium/chrome/browser/resources/print_preview/data/margins.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('print_preview.ticket_items', function() {
+cr.define('print_preview', function() {
'use strict';
/**
@@ -21,7 +21,7 @@ cr.define('print_preview.ticket_items', function() {
* printing/print_job_constants.h.
* @enum {number}
*/
- const MarginsTypeValue = {
+ const MarginsType = {
DEFAULT: 0,
NO_MARGINS: 1,
MINIMUM: 2,
@@ -30,7 +30,7 @@ cr.define('print_preview.ticket_items', function() {
return {
CustomMarginsOrientation: CustomMarginsOrientation,
- MarginsTypeValue: MarginsTypeValue,
+ MarginsType: MarginsType,
};
});
@@ -61,18 +61,14 @@ cr.define('print_preview', function() {
/**
* Backing store for the margin values in points.
* @type {!Object<
- * !print_preview.ticket_items.CustomMarginsOrientation, number>}
+ * !print_preview.CustomMarginsOrientation, number>}
* @private
*/
this.value_ = {};
- this.value_[print_preview.ticket_items.CustomMarginsOrientation.TOP] =
- top;
- this.value_[print_preview.ticket_items.CustomMarginsOrientation.RIGHT] =
- right;
- this.value_[print_preview.ticket_items.CustomMarginsOrientation.BOTTOM] =
- bottom;
- this.value_[print_preview.ticket_items.CustomMarginsOrientation.LEFT] =
- left;
+ this.value_[print_preview.CustomMarginsOrientation.TOP] = top;
+ this.value_[print_preview.CustomMarginsOrientation.RIGHT] = right;
+ this.value_[print_preview.CustomMarginsOrientation.BOTTOM] = bottom;
+ this.value_[print_preview.CustomMarginsOrientation.LEFT] = left;
}
/**
@@ -83,15 +79,14 @@ cr.define('print_preview', function() {
*/
static parse(state) {
return new print_preview.Margins(
- state[print_preview.ticket_items.CustomMarginsOrientation.TOP] || 0,
- state[print_preview.ticket_items.CustomMarginsOrientation.RIGHT] || 0,
- state[print_preview.ticket_items.CustomMarginsOrientation.BOTTOM] ||
- 0,
- state[print_preview.ticket_items.CustomMarginsOrientation.LEFT] || 0);
+ state[print_preview.CustomMarginsOrientation.TOP] || 0,
+ state[print_preview.CustomMarginsOrientation.RIGHT] || 0,
+ state[print_preview.CustomMarginsOrientation.BOTTOM] || 0,
+ state[print_preview.CustomMarginsOrientation.LEFT] || 0);
}
/**
- * @param {!print_preview.ticket_items.CustomMarginsOrientation}
+ * @param {!print_preview.CustomMarginsOrientation}
* orientation Specifies the margin value to get.
* @return {number} Value of the margin of the given orientation.
*/
@@ -100,7 +95,7 @@ cr.define('print_preview', function() {
}
/**
- * @param {!print_preview.ticket_items.CustomMarginsOrientation}
+ * @param {!print_preview.CustomMarginsOrientation}
* orientation Specifies the margin to set.
* @param {number} value Updated value of the margin in points to modify.
* @return {!print_preview.Margins} A new copy of |this| with the
@@ -110,10 +105,10 @@ cr.define('print_preview', function() {
const newValue = this.clone_();
newValue[orientation] = value;
return new Margins(
- newValue[print_preview.ticket_items.CustomMarginsOrientation.TOP],
- newValue[print_preview.ticket_items.CustomMarginsOrientation.RIGHT],
- newValue[print_preview.ticket_items.CustomMarginsOrientation.BOTTOM],
- newValue[print_preview.ticket_items.CustomMarginsOrientation.LEFT]);
+ newValue[print_preview.CustomMarginsOrientation.TOP],
+ newValue[print_preview.CustomMarginsOrientation.RIGHT],
+ newValue[print_preview.CustomMarginsOrientation.BOTTOM],
+ newValue[print_preview.CustomMarginsOrientation.LEFT]);
}
/**
diff --git a/chromium/chrome/browser/resources/print_preview/data/model.html b/chromium/chrome/browser/resources/print_preview/data/model.html
index c29628bb3fa..1fb0c92a112 100644
--- a/chromium/chrome/browser/resources/print_preview/data/model.html
+++ b/chromium/chrome/browser/resources/print_preview/data/model.html
@@ -3,7 +3,9 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/html/promise_resolver.html">
<link rel="import" href="destination.html">
+<link rel="import" href="destination_match.html">
<link rel="import" href="document_info.html">
<link rel="import" href="margins.html">
+<link rel="import" href="scaling.html">
<script src="model.js"></script>
diff --git a/chromium/chrome/browser/resources/print_preview/data/model.js b/chromium/chrome/browser/resources/print_preview/data/model.js
index 4e5182375ae..bcdc1711aa4 100644
--- a/chromium/chrome/browser/resources/print_preview/data/model.js
+++ b/chromium/chrome/browser/resources/print_preview/data/model.js
@@ -30,8 +30,9 @@ cr.define('print_preview', function() {
* mediaSize: !print_preview.Setting,
* margins: !print_preview.Setting,
* dpi: !print_preview.Setting,
- * fitToPage: !print_preview.Setting,
* scaling: !print_preview.Setting,
+ * scalingType: !print_preview.Setting,
+ * scalingTypePdf: !print_preview.Setting,
* duplex: !print_preview.Setting,
* duplexShortEdge: !print_preview.Setting,
* cssBackground: !print_preview.Setting,
@@ -60,16 +61,17 @@ cr.define('print_preview', function() {
* width_microns: number,
* custom_display_name: (string | undefined),
* is_default: (boolean | undefined)} | undefined),
- * marginsType: (print_preview.ticket_items.MarginsTypeValue | undefined),
+ * marginsType: (print_preview.MarginsType | 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),
+ * scalingType: (print_preview.ScalingType | undefined),
+ * scalingTypePdf: (print_preview.ScalingType | undefined),
* vendor_options: (Object | undefined),
* isPinEnabled: (boolean | undefined),
* pinValue: (string | undefined)
@@ -147,8 +149,7 @@ cr.define('print_preview.Model', () => {
'use strict';
/**
- * Sticky setting names. Alphabetical except for fitToPage, which must be set
- * after scaling in updateFromStickySettings().
+ * Sticky setting names in alphabetical order.
* @type {!Array<string>}
*/
const STICKY_SETTING_NAMES = [
@@ -164,9 +165,9 @@ const STICKY_SETTING_NAMES = [
'layout',
'margins',
'mediaSize',
- 'customScaling',
'scaling',
- 'fitToPage',
+ 'scalingType',
+ 'scalingTypePdf',
'vendorItems',
];
// <if expr="chromeos">
@@ -188,9 +189,9 @@ Polymer({
/**
* Object containing current settings of Print Preview, for use by Polymer
* controls.
- * Initialize settings that are only available on some printers to
- * unavailable, and settings that are provided by PDF generation to
- * available.
+ * Initialize all settings to available so that more settings always stays
+ * in a collapsed state during startup, when document information and
+ * printer capabilities may arrive at slightly different times.
* @type {!print_preview.Settings}
*/
settings: {
@@ -242,7 +243,7 @@ Polymer({
value: true, /* color */
unavailableValue: false,
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'isColorEnabled',
@@ -255,16 +256,15 @@ Polymer({
height_microns: 279400,
},
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'mediaSize',
updatesPreview: true,
},
margins: {
- value: print_preview.ticket_items.MarginsTypeValue.DEFAULT,
- unavailableValue:
- print_preview.ticket_items.MarginsTypeValue.DEFAULT,
+ value: print_preview.MarginsType.DEFAULT,
+ unavailableValue: print_preview.MarginsType.DEFAULT,
valid: true,
available: true,
setByPolicy: false,
@@ -286,47 +286,47 @@ Polymer({
value: {},
unavailableValue: {},
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'dpi',
updatesPreview: false,
},
- fitToPage: {
- value: false,
- unavailableValue: false,
+ scaling: {
+ value: '100',
+ unavailableValue: '100',
valid: true,
available: true,
setByPolicy: false,
setFromUi: false,
- key: 'isFitToPageEnabled',
+ key: 'scaling',
updatesPreview: true,
},
- scaling: {
- value: '100',
- unavailableValue: '100',
+ scalingType: {
+ value: print_preview.ScalingType.DEFAULT,
+ unavailableValue: print_preview.ScalingType.DEFAULT,
valid: true,
available: true,
setByPolicy: false,
setFromUi: false,
- key: 'scaling',
+ key: 'scalingType',
updatesPreview: true,
},
- customScaling: {
- value: false,
- unavailableValue: false,
+ scalingTypePdf: {
+ value: print_preview.ScalingType.DEFAULT,
+ unavailableValue: print_preview.ScalingType.DEFAULT,
valid: true,
available: true,
setByPolicy: false,
setFromUi: false,
- key: 'customScaling',
+ key: 'scalingTypePdf',
updatesPreview: true,
},
duplex: {
value: true,
unavailableValue: false,
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'isDuplexEnabled',
@@ -386,7 +386,7 @@ Polymer({
value: {},
unavailableValue: {},
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'vendorOptions',
@@ -441,7 +441,7 @@ Polymer({
value: false,
unavailableValue: false,
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'isPinEnabled',
@@ -451,7 +451,7 @@ Polymer({
value: '',
unavailableValue: '',
valid: true,
- available: false,
+ available: true,
setByPolicy: false,
setFromUi: false,
key: 'pinValue',
@@ -484,8 +484,8 @@ Polymer({
observers: [
'updateSettingsFromDestination_(destination.capabilities)',
'updateSettingsAvailabilityFromDocumentSettings_(' +
- 'documentSettings.isModifiable, documentSettings.hasCssMediaStyles,' +
- 'documentSettings.hasSelection)',
+ 'documentSettings.isModifiable, documentSettings.isPdf,' +
+ 'documentSettings.hasCssMediaStyles, documentSettings.hasSelection)',
'updateHeaderFooterAvailable_(' +
'margins, settings.margins.value, ' +
'settings.customMargins.value, settings.mediaSize.value)',
@@ -706,11 +706,15 @@ Polymer({
const knownSizeToSaveAsPdf = isSaveAsPDF &&
(!this.documentSettings.isModifiable ||
this.documentSettings.hasCssMediaStyles);
- this.setSettingPath_('fitToPage.unavailableValue', !isSaveAsPDF);
+ const scalingAvailable = !knownSizeToSaveAsPdf &&
+ (this.documentSettings.isModifiable || this.documentSettings.isPdf);
+ this.setSettingPath_('scaling.available', scalingAvailable);
this.setSettingPath_(
- 'fitToPage.available',
- !knownSizeToSaveAsPdf && !this.documentSettings.isModifiable);
- this.setSettingPath_('scaling.available', !knownSizeToSaveAsPdf);
+ 'scalingType.available',
+ scalingAvailable && !this.documentSettings.isPdf);
+ this.setSettingPath_(
+ 'scalingTypePdf.available',
+ scalingAvailable && this.documentSettings.isPdf);
const caps = this.destination && this.destination.capabilities ?
this.destination.capabilities.printer :
null;
@@ -727,6 +731,9 @@ Polymer({
}
this.setSettingPath_(
+ 'pagesPerSheet.available',
+ this.documentSettings.isModifiable || this.documentSettings.isPdf);
+ this.setSettingPath_(
'margins.available', this.documentSettings.isModifiable);
this.setSettingPath_(
'customMargins.available', this.documentSettings.isModifiable);
@@ -784,22 +791,20 @@ Polymer({
// Otherwise, availability depends on the margins.
let available = false;
const marginsType =
- /** @type {!print_preview.ticket_items.MarginsTypeValue} */ (
+ /** @type {!print_preview.MarginsType} */ (
this.getSettingValue('margins'));
switch (marginsType) {
- case print_preview.ticket_items.MarginsTypeValue.DEFAULT:
+ case print_preview.MarginsType.DEFAULT:
available = !this.margins ||
- this.margins.get(
- print_preview.ticket_items.CustomMarginsOrientation.TOP) > 0 ||
- this.margins.get(
- print_preview.ticket_items.CustomMarginsOrientation.BOTTOM) > 0;
+ this.margins.get(print_preview.CustomMarginsOrientation.TOP) > 0 ||
+ this.margins.get(print_preview.CustomMarginsOrientation.BOTTOM) > 0;
break;
- case print_preview.ticket_items.MarginsTypeValue.NO_MARGINS:
+ case print_preview.MarginsType.NO_MARGINS:
break;
- case print_preview.ticket_items.MarginsTypeValue.MINIMUM:
+ case print_preview.MarginsType.MINIMUM:
available = true;
break;
- case print_preview.ticket_items.MarginsTypeValue.CUSTOM:
+ case print_preview.MarginsType.CUSTOM:
const margins = this.getSettingValue('customMargins');
available = margins.marginTop > 0 || margins.marginBottom > 0;
break;
@@ -1017,21 +1022,14 @@ Polymer({
},
applyStickySettings: function() {
- const defaultScaling = '100';
if (this.stickySettings_) {
STICKY_SETTING_NAMES.forEach(settingName => {
const setting = this.get(settingName, this.settings);
const value = this.stickySettings_[setting.key];
if (value != undefined) {
this.setSetting(settingName, value);
- } else if (
- settingName === 'customScaling' &&
- !!this.stickySettings_['scaling']) {
- // If users with an old set of sticky settings intentionally set a non
- // default value, set customScaling to true so the value is restored.
- // Otherwise, set to false with noSticky=true.
- const scalingIsDefault = this.stickySettings_['scaling'] === '100';
- this.setSetting(settingName, !scalingIsDefault, scalingIsDefault);
+ } else {
+ this.applyScalingStickySettings_(settingName);
}
});
}
@@ -1052,6 +1050,39 @@ Polymer({
this.fire('sticky-settings-changed', this.getStickySettings_());
},
+ /**
+ * Helper function for applyStickySettings(). Checks if the setting
+ * is a scaling setting and applies by applying the old types
+ * that rely on 'fitToPage' and 'customScaling'.
+ * @param {string} settingName Name of the setting being applied.
+ * @private
+ */
+ applyScalingStickySettings_: function(settingName) {
+ // TODO(dhoss): Remove checks for 'customScaling' and 'fitToPage'
+ if (settingName === 'scalingType' &&
+ 'customScaling' in this.stickySettings_) {
+ const isCustom = this.stickySettings_['customScaling'];
+ const scalingType = isCustom ? print_preview.ScalingType.CUSTOM :
+ print_preview.ScalingType.DEFAULT;
+ this.setSetting(settingName, scalingType);
+ } else if (settingName === 'scalingTypePdf') {
+ if ('isFitToPageEnabled' in this.stickySettings_) {
+ const isFitToPage = this.stickySettings_['isFitToPageEnabled'];
+ const scalingTypePdf = isFitToPage ?
+ print_preview.ScalingType.FIT_TO_PAGE :
+ this.getSetting('scalingType').value;
+ this.setSetting(settingName, scalingTypePdf);
+ } else if (
+ this.getSetting('scalingType').value ===
+ print_preview.ScalingType.CUSTOM) {
+ // In the event that 'isFitToPageEnabled' was not in the sticky
+ // settings, and 'scalingType' has been set to custom, we want
+ // 'scalingTypePdf' to match.
+ this.setSetting(settingName, print_preview.ScalingType.CUSTOM);
+ }
+ }
+ },
+
// <if expr="chromeos">
/**
* Restricts settings and applies defaults as defined by policy applicable to
@@ -1066,7 +1097,7 @@ Polymer({
// We want to set the value nevertheless so we call |this.set| directly.
this.set(
'settings.color.value',
- colorValue == print_preview.ColorModeRestriction.COLOR);
+ colorValue === print_preview.ColorModeRestriction.COLOR);
}
this.set('settings.color.setByPolicy', !!colorPolicy);
@@ -1093,7 +1124,7 @@ Polymer({
!!duplexPolicy && setDuplexTypeByPolicy);
const pinPolicy = this.destination.pinPolicy;
- if (pinPolicy == print_preview.PinModeRestriction.NO_PIN) {
+ if (pinPolicy === print_preview.PinModeRestriction.NO_PIN) {
this.set('settings.pin.available', false);
this.set('settings.pinValue.available', false);
}
@@ -1101,10 +1132,22 @@ Polymer({
if (pinValue) {
this.set(
'settings.pin.value',
- pinValue == print_preview.PinModeRestriction.PIN);
+ pinValue === print_preview.PinModeRestriction.PIN);
}
this.set('settings.pin.setByPolicy', !!pinPolicy);
+ const backgroundGraphicsPolicy = this.destination.backgroundGraphicsPolicy;
+ const backgroundGraphicsValue = backgroundGraphicsPolicy ?
+ backgroundGraphicsPolicy :
+ this.destination.defaultBackgroundGraphicsPolicy;
+ if (backgroundGraphicsValue) {
+ this.set(
+ 'settings.cssBackground.value',
+ backgroundGraphicsValue ===
+ print_preview.BackgroundGraphicsModeRestriction.ENABLED);
+ }
+ this.set('settings.cssBackground.setByPolicy', !!backgroundGraphicsPolicy);
+
this.updateManaged_();
},
// </if>
@@ -1113,8 +1156,8 @@ Polymer({
updateManaged_: function() {
let managedSettings = ['headerFooter'];
// <if expr="chromeos">
- managedSettings =
- managedSettings.concat(['color', 'duplex', 'duplexShortEdge', 'pin']);
+ managedSettings = managedSettings.concat(
+ ['color', 'cssBackground', 'duplex', 'duplexShortEdge', 'pin']);
// </if>
this.controlsManaged = managedSettings.some(settingName => {
const setting = this.getSetting(settingName);
@@ -1191,6 +1234,9 @@ Polymer({
vendor_id: (number | undefined)}}
*/
(this.getSettingValue('dpi'));
+ const scalingSettingKey = this.getSetting('scalingTypePdf').available ?
+ 'scalingTypePdf' :
+ 'scalingType';
const ticket = {
mediaSize: this.getSettingValue('mediaSize'),
pageCount: this.getSettingValue('pages').length,
@@ -1205,23 +1251,20 @@ Polymer({
shouldPrintBackgrounds: this.getSettingValue('cssBackground'),
shouldPrintSelectionOnly: false, // only used in print preview
previewModifiable: this.documentSettings.isModifiable,
- printToPDF: destination.id ==
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
printToGoogleDrive:
destination.id == print_preview.Destination.GooglePromotedId.DOCS,
- printWithCloudPrint: !destination.isLocal,
- printWithPrivet: destination.isPrivet,
- printWithExtension: destination.isExtension,
+ printerType: print_preview.getPrinterTypeForDestination(destination),
rasterizePDF: this.getSettingValue('rasterize'),
- scaleFactor: this.getSettingValue('customScaling') ?
+ scaleFactor: this.getSettingValue(scalingSettingKey) ===
+ print_preview.ScalingType.CUSTOM ?
parseInt(this.getSettingValue('scaling'), 10) :
100,
+ scalingType: this.getSettingValue(scalingSettingKey),
pagesPerSheet: this.getSettingValue('pagesPerSheet'),
dpiHorizontal: (dpi && 'horizontal_dpi' in dpi) ? dpi.horizontal_dpi : 0,
dpiVertical: (dpi && 'vertical_dpi' in dpi) ? dpi.vertical_dpi : 0,
dpiDefault: (dpi && 'is_default' in dpi) ? dpi.is_default : false,
deviceName: destination.id,
- fitToPageEnabled: this.getSettingValue('fitToPage'),
pageWidth: this.pageSize.width,
pageHeight: this.pageSize.height,
showSystemDialog: showSystemDialog,
@@ -1232,8 +1275,7 @@ Polymer({
ticket.cloudPrintID = destination.id;
}
- if (this.getSettingValue('margins') ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ if (this.getSettingValue('margins') == print_preview.MarginsType.CUSTOM) {
ticket.marginsCustom = this.getSettingValue('customMargins');
}
@@ -1252,6 +1294,9 @@ Polymer({
if (this.getSettingValue('pin')) {
ticket.pinValue = this.getSettingValue('pinValue');
}
+ if (destination.origin == print_preview.DestinationOrigin.CROS) {
+ ticket.advancedSettings = this.getSettingValue('vendorItems');
+ }
// </if>
return JSON.stringify(ticket);
diff --git a/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.html b/chromium/chrome/browser/resources/print_preview/data/scaling.html
index 0336d1ff108..cbaac092c4e 100644
--- a/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.html
+++ b/chromium/chrome/browser/resources/print_preview/data/scaling.html
@@ -1,2 +1,3 @@
<link rel="import" href="chrome://resources/html/cr.html">
-<script src="bookmark_proxy.js"></script> \ No newline at end of file
+
+<script src="scaling.js"></script>
diff --git a/chromium/chrome/browser/resources/print_preview/data/scaling.js b/chromium/chrome/browser/resources/print_preview/data/scaling.js
new file mode 100644
index 00000000000..49c8d5b912d
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/data/scaling.js
@@ -0,0 +1,24 @@
+// Copyright (c) 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('print_preview', function() {
+ 'use strict';
+
+ /**
+ * Must be kept in sync with the C++ ScalingType enum in
+ * printing/print_job_constants.h.
+ * @enum {number}
+ */
+ const ScalingType = {
+ DEFAULT: 0,
+ FIT_TO_PAGE: 1,
+ FIT_TO_PAPER: 2,
+ CUSTOM: 3,
+ };
+
+ // Export
+ return {
+ ScalingType: ScalingType,
+ };
+});
diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js
index ddf522abeb6..8a5abc38989 100644
--- a/chromium/chrome/browser/resources/print_preview/native_layer.js
+++ b/chromium/chrome/browser/resources/print_preview/native_layer.js
@@ -37,6 +37,7 @@ cr.define('print_preview', function() {
* decimalDelimiter: string,
* unitType: !print_preview.MeasurementSystemUnitType,
* previewModifiable: boolean,
+ * previewIsPdf: boolean,
* documentTitle: string,
* documentHasSelection: boolean,
* shouldPrintSelectionOnly: boolean,
@@ -98,19 +99,6 @@ cr.define('print_preview', function() {
let ProvisionalDestinationInfo;
/**
- * Printer types for capabilities and printer list requests.
- * Should match PrinterType in print_preview_handler.h
- * @enum {number}
- */
- const PrinterType = {
- PRIVET_PRINTER: 0,
- EXTENSION_PRINTER: 1,
- PDF_PRINTER: 2,
- LOCAL_PRINTER: 3,
- CLOUD_PRINTER: 4
- };
-
- /**
* An interface to the native Chromium printing system layer.
*/
class NativeLayer {
@@ -329,7 +317,6 @@ cr.define('print_preview', function() {
NativeLayer: NativeLayer,
PreviewSettings: PreviewSettings,
PrinterSetupResponse: PrinterSetupResponse,
- PrinterType: PrinterType,
PrivetPrinterDescription: PrivetPrinterDescription,
ProvisionalDestinationInfo: ProvisionalDestinationInfo,
};
diff --git a/chromium/chrome/browser/resources/print_preview/polymer3/demo.js b/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
index 39a1b1bc694..7e062bfa5e7 100644
--- a/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
+++ b/chromium/chrome/browser/resources/print_preview/polymer3/demo.js
@@ -2,33 +2,68 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'chrome://resources/cr_components/managed_footnote/managed_footnote.m.js';
+import 'chrome://resources/cr_elements/action_link_css.m.js';
+import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.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_expand_button/cr_expand_button.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_lazy_render/cr_lazy_render.m.js';
+import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.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/cr_toolbar/cr_toolbar.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/md_select_css.m.js';
+import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
+import 'chrome://resources/js/action_link.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../strings.m.js';
+import * as crToastManager from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.m.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
class HelloPolymer3Element extends PolymerElement {
static get template() {
return html`
- <style include="md-select">
+ <style include="md-select action-link">
cr-toggle {
display: inline-block;
}
+
+ cr-icon-button {
+ --cr-icon-button-color: white;
+ }
+
+ .setting {
+ align-items: center;
+ display: flex;
+ }
+
+ div, cr-input, select, cr-checkbox {
+ margin-top: 20px;
+ }
</style>
+ <cr-toolbar id="toolbar" page-name="Polymer 3 Demo"
+ search-prompt="Search">
+ <cr-icon-button iron-icon="cr:more-vert" on-click="showActionMenu_">
+ </cr-icon-button>
+ </cr-toolbar>
+ <cr-action-menu>
+ <button class="dropdown-item">Hello</button>
+ <button class="dropdown-item">Action</button>
+ <button class="dropdown-item">Menu</button>
+ </cr-action-menu>
+
<cr-checkbox checked="{{checkboxChecked_}}">
[[checkboxChecked_]]
</cr-checkbox>
@@ -47,8 +82,6 @@ class HelloPolymer3Element extends PolymerElement {
<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>
@@ -86,14 +119,49 @@ class HelloPolymer3Element extends PolymerElement {
<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>
+ <cr-lazy-render id="dialog">
+ <template>
+ <cr-dialog>
+ <div slot="title">I am a dialog</div>
+ </cr-dialog>
+ </template>
+ </cr-lazy-render>
</div>
<div>
<cr-search-field label="test search field"></cr-search-field>
+ </div>
+
<div>
+ <cr-expand-button on-click="onExpand_">Expand</cr-expand-button>
+ <div hidden$="[[!expanded_]]">Expanded content</div>
+ </div>
+
+ <div class="setting">
+ <span>Some setting</span>
+ <cr-tooltip-icon tooltip-text="This setting is controlled by policy"
+ icon-class="cr20:domain"
+ icon-aria-label="This setting is controlled by policy">
+ </cr-tooltip-icon>
+ <cr-toggle disabled checked></cr-toggle>
+ </div>
+
+ <div>
+ <cr-link-row class="hr" label="Hello Link Row"></cr-link-row>
+ </div>
+
+ <a is="action-link">I am an action link</a>
+
+ <div>
+ <cr-toast-manager></cr-toast-manager>
+ <cr-button on-click="showToastWithManager_">
+ Show toast for 2s
+ </cr-button>
+ </div>
+
+ <div>
+ <managed-footnote></managed-footnote>
+ </div>
`;
}
@@ -106,6 +174,12 @@ class HelloPolymer3Element extends PolymerElement {
checkboxChecked_: Boolean,
/** @private */
+ expanded_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /** @private */
selectedSubpage_: {
type: Number,
value: 0,
@@ -116,6 +190,12 @@ class HelloPolymer3Element extends PolymerElement {
type: Array,
value: () => (['A', 'B']),
},
+
+ /** @private */
+ isFirst_: {
+ type: Boolean,
+ value: true,
+ },
};
}
@@ -131,7 +211,7 @@ class HelloPolymer3Element extends PolymerElement {
/** @private */
showDialog_() {
- this.shadowRoot.querySelector('cr-dialog').showModal();
+ this.shadowRoot.querySelector('#dialog').get().showModal();
}
/**
@@ -149,6 +229,28 @@ class HelloPolymer3Element extends PolymerElement {
isTabBSelected_() {
return this.selectedSubpage_ === 1;
}
+
+ /** @private */
+ onExpand_() {
+ this.expanded_ = !this.expanded_;
+ }
+
+ /**
+ * @param {!Event} e
+ * @private
+ */
+ showActionMenu_(e) {
+ this.shadowRoot.querySelector('cr-action-menu').showAt(e.target);
+ }
+
+ /** @private */
+ showToastWithManager_() {
+ const toastManager = crToastManager.getInstance();
+ toastManager.duration = 2000;
+ toastManager.show(
+ 'I am toasted ' + (this.isFirst_ ? 'first' : 'second'), false);
+ this.isFirst_ = !this.isFirst_;
+ }
} // class HelloPolymer3
customElements.define('hello-polymer3', HelloPolymer3Element);
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd b/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
index 41d460f7452..25005669658 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
+++ b/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
@@ -145,6 +145,12 @@
<structure name="IDR_PRINT_PREVIEW_DATA_DOCUMENT_INFO_JS"
file="data/document_info.js"
type="chrome_html" />
+ <structure name="IDR_PRINT_PREVIEW_DATA_SCALING_HTML"
+ file="data/scaling.html"
+ type="chrome_html" />
+ <structure name="IDR_PRINT_PREVIEW_DATA_SCALING_JS"
+ file="data/scaling.js"
+ type="chrome_html" />
<structure name="IDR_PRINT_PREVIEW_DATA_SIZE_HTML"
file="data/size.html"
type="chrome_html" />
@@ -432,8 +438,8 @@
<structure name="IDR_PRINT_PREVIEW_UI_STRINGS_HTML"
file="ui/strings.html"
type="chrome_html" />
- <structure name="IDR_PRINT_PREVIEW_ICONS_HTML"
- file="icons.html"
+ <structure name="IDR_PRINT_PREVIEW_UI_ICONS_HTML"
+ file="ui/icons.html"
type="chrome_html" />
<if expr="not optimize_webui">
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview_utils.js b/chromium/chrome/browser/resources/print_preview/print_preview_utils.js
index 009f602c06e..cf7256fbce1 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview_utils.js
+++ b/chromium/chrome/browser/resources/print_preview/print_preview_utils.js
@@ -59,7 +59,7 @@ function observerDepsDefined(args) {
/**
* Returns background images (icon and dropdown arrow) for use in a md-select.
- * @param {!Polymer.IronIconsetSvg} iconset The iconset the icon is in.
+ * @param {!IronIconsetSvgElement} iconset The iconset the icon is in.
* @param {string} iconName The icon name
* @param {!HTMLElement} el The element that contains the select.
* @return {string} String containing inlined SVG of the icon and
diff --git a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
index 488bf4143ba..5b144bb14df 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
@@ -151,10 +151,10 @@ js_library("destination_select") {
":select_behavior",
"..:print_preview_utils",
"../data:destination",
+ "//third_party/polymer/v1_0/components-chromium/iron-iconset-svg:iron-iconset-svg-extracted",
"//third_party/polymer/v1_0/components-chromium/iron-meta:iron-meta-extracted",
"//ui/webui/resources/js:i18n_behavior",
]
- externs_list = [ "$externs_path/pending.js" ]
}
if (is_chromeos) {
@@ -232,6 +232,7 @@ js_library("scaling_settings") {
deps = [
":number_settings_section",
":settings_behavior",
+ "../data:scaling",
]
}
@@ -246,8 +247,8 @@ js_library("duplex_settings") {
":select_behavior",
":settings_behavior",
"..:print_preview_utils",
+ "//third_party/polymer/v1_0/components-chromium/iron-iconset-svg:iron-iconset-svg-extracted",
]
- externs_list = [ "$externs_path/pending.js" ]
}
js_library("advanced_options_settings") {
@@ -317,6 +318,7 @@ js_library("preview_area") {
"../../pdf:pdf_scripting_api",
"../data:coordinate2d",
"../data:destination",
+ "../data:destination_match",
"../data:margins",
"../data:model",
"../data:printable_area",
@@ -376,6 +378,7 @@ js_library("destination_dialog") {
"//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:list_property_update_behavior",
]
+ externs_list = [ "$externs_path/pending_polymer.js" ]
}
js_library("destination_list") {
diff --git a/chromium/chrome/browser/resources/print_preview/ui/advanced_options_settings.html b/chromium/chrome/browser/resources/print_preview/ui/advanced_options_settings.html
index 4cffcd9b8e9..ec2c7ba8213 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/advanced_options_settings.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/advanced_options_settings.html
@@ -10,6 +10,7 @@
<template>
<style include="print-preview-shared">
cr-button {
+ height: fit-content;
min-height: 32px;
text-align: center;
width: calc(100% - 2 * var(--print-preview-sidebar-margin));
diff --git a/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.html b/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.html
index 2dd7432984d..396e8525c4f 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.html
@@ -1,6 +1,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
<link rel="import" href="chrome://resources/cr_elements/search_highlight_style_css.html">
<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
@@ -76,11 +77,16 @@
</select>
</div>
</template>
- <span hidden$="[[isCapabilityTypeSelect_(capability)]]">
+ <span hidden$="[[!isCapabilityTypeInput_(capability)]]">
<cr-input type="text" on-input="onUserInput_" spellcheck="false"
placeholder="[[getCapabilityPlaceholder_(capability)]]">
</cr-input>
</span>
+ <span hidden$="[[!isCapabilityTypeCheckbox_(capability)]]">
+ <cr-checkbox on-change="onCheckboxInput_"
+ checked="[[isChecked_(currentValue_)]]">
+ </cr-checkbox>
+ </span>
</div>
</template>
<script src="advanced_settings_item.js"></script>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.js b/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.js
index 4b01e0ef35f..56450e98237 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/advanced_settings_item.js
@@ -67,6 +67,33 @@ Polymer({
},
/**
+ * @return {boolean} Whether the capability represented by this item is
+ * of type checkbox.
+ * @private
+ */
+ isCapabilityTypeCheckbox_: function() {
+ return this.capability.type == 'TYPED_VALUE' &&
+ this.capability.typed_value_cap.value_type == 'BOOLEAN';
+ },
+
+ /**
+ * @return {boolean} Whether the capability represented by this item is
+ * of type input.
+ * @private
+ */
+ isCapabilityTypeInput_: function() {
+ return !this.isCapabilityTypeSelect_() && !this.isCapabilityTypeCheckbox_();
+ },
+
+ /**
+ * @return {boolean} Whether the checkbox setting is checked.
+ * @private
+ */
+ isChecked_: function() {
+ return this.currentValue_ == 'true';
+ },
+
+ /**
* @param {!print_preview.VendorCapabilitySelectOption} option The option
* for a select capability.
* @return {boolean} Whether the option is selected.
@@ -137,6 +164,14 @@ Polymer({
},
/**
+ * @param {!Event} e Event containing the new value.
+ * @private
+ */
+ onCheckboxInput_: function(e) {
+ this.currentValue_ = e.target.checked ? 'true' : 'false';
+ },
+
+ /**
* @return {string} The current value of the setting, or the empty string if
* it is not set.
*/
diff --git a/chromium/chrome/browser/resources/print_preview/ui/app.html b/chromium/chrome/browser/resources/print_preview/ui/app.html
index 2e5816ecc93..d5ad5503a1a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/app.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/app.html
@@ -73,7 +73,8 @@
cloud-print-error-message="[[cloudPrintErrorMessage_]]"
destination-state="{{destinationState_}}"
controls-managed="[[controlsManaged_]]" destination="{{destination_}}"
- error="{{error_}}" new-print-preview-layout="[[newPrintPreviewLayout_]]"
+ error="{{error_}}" is-pdf="[[documentSettings_.isPdf]]"
+ new-print-preview-layout="[[newPrintPreviewLayout_]]"
page-count="[[documentSettings_.pageCount]]"
settings="[[settings]]" state="[[state]]" on-focus="onSidebarFocus_"
<if expr="is_macosx">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/app.js b/chromium/chrome/browser/resources/print_preview/ui/app.js
index 8f30d4e6358..ccd7ca5e5e7 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/app.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/app.js
@@ -266,8 +266,8 @@ Polymer({
settings.uiLocale);
}
this.$.documentInfo.init(
- settings.previewModifiable, settings.documentTitle,
- settings.documentHasSelection);
+ settings.previewModifiable, settings.previewIsPdf,
+ settings.documentTitle, settings.documentHasSelection);
this.$.model.setStickySettings(settings.serializedAppStateStr);
this.$.model.setPolicySettings(
settings.headerFooter, settings.isHeaderFooterManaged);
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html
index a941dae7276..a9f91768268 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.html
@@ -16,7 +16,7 @@
<link rel="import" href="chrome://resources/html/list_property_update_behavior.html">
<link rel="import" href="chrome://resources/cr_elements/md_select_css.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="icons.html">
<link rel="import" href="../metrics.html">
<link rel="import" href="../native_layer.html">
<link rel="import" href="../print_preview_utils.html">
@@ -166,7 +166,8 @@
</select>
</div>
<print-preview-search-box id="searchBox"
- label="$i18n{searchBoxPlaceholder}" search-query="{{searchQuery_}}">
+ label="$i18n{searchBoxPlaceholder}" search-query="{{searchQuery_}}"
+ autofocus>
</print-preview-search-box>
</div>
<div slot="body">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
index 5c30560c050..06dabe3874a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
@@ -287,12 +287,6 @@ Polymer({
show: function() {
this.$.dialog.showModal();
- // Note: Manually focusing here instead of using autofocus, as it is
- // currently not possible to validate refocusing of the search input if
- // autofocus is used. See https://crbug.com/985637 and
- // https://crbug.com/985636. Autofocus can be restored when one or both of
- // these issues are resolved.
- this.$.searchBox.focus();
this.loadingDestinations_ = this.destinationStore === undefined ||
this.destinationStore.isPrintDestinationSearchInProgress;
this.metrics_.record(
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_list_item.html b/chromium/chrome/browser/resources/print_preview/ui/destination_list_item.html
index 5e6056eb752..2a98fe8fd59 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_list_item.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_list_item.html
@@ -6,7 +6,7 @@
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/html/load_time_data.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="icons.html">
<link rel="import" href="../data/destination.html">
<link rel="import" href="highlight_utils.html">
<link rel="import" href="print_preview_vars_css.html">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select.html b/chromium/chrome/browser/resources/print_preview/ui/destination_select.html
index 2b7cb3cec17..2438ba0e47b 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_select.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select.html
@@ -7,7 +7,7 @@
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-meta/iron-meta.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="icons.html">
<link rel="import" href="../print_preview_utils.html">
<link rel="import" href="../data/destination.html">
<link rel="import" href="print_preview_shared_css.html">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select.js b/chromium/chrome/browser/resources/print_preview/ui/destination_select.js
index 2c68355bd2a..d725445e819 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_select.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select.js
@@ -76,7 +76,7 @@ Polymer({
}
// </if>
iconSetAndIcon = iconSetAndIcon || icon.split(':');
- const iconset = /** @type {!Polymer.IronIconsetSvg} */ (
+ const iconset = /** @type {!IronIconsetSvgElement} */ (
this.meta_.byKey(iconSetAndIcon[0]));
return getSelectDropdownBackground(iconset, iconSetAndIcon[1], this);
},
diff --git a/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.html b/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.html
index a1382d8bc8d..c1393ed1e50 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.html
@@ -6,7 +6,7 @@
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-meta/iron-meta.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="icons.html">
<link rel="import" href="../print_preview_utils.html">
<link rel="import" href="print_preview_shared_css.html">
<link rel="import" href="select_behavior.html">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.js b/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.js
index 167c1fc7342..22b0820adf3 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/duplex_settings.js
@@ -81,7 +81,7 @@ Polymer({
getBackgroundImages_: function() {
const icon =
this.getSettingValue('duplexShortEdge') ? 'short-edge' : 'long-edge';
- const iconset = /** @type {!Polymer.IronIconsetSvg} */ (
+ const iconset = /** @type {!IronIconsetSvgElement} */ (
this.meta_.byKey('print-preview'));
return getSelectDropdownBackground(iconset, icon, this);
},
diff --git a/chromium/chrome/browser/resources/print_preview/ui/header.html b/chromium/chrome/browser/resources/print_preview/ui/header.html
index 8e92fdd887f..0b9152f23a7 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/header.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/header.html
@@ -6,7 +6,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="../data/destination.html">
<link rel="import" href="../data/state.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="icons.html">
<link rel="import" href="settings_behavior.html">
<link rel="import" href="print_preview_vars_css.html">
<link rel="import" href="strings.html">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/header_new.html b/chromium/chrome/browser/resources/print_preview/ui/header_new.html
index 9983f9f2b24..6a16578d5b6 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/header_new.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/header_new.html
@@ -5,7 +5,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="../data/destination.html">
<link rel="import" href="../data/state.html">
-<link rel="import" href="../icons.html">
+<link rel="import" href="icons.html">
<link rel="import" href="settings_behavior.html">
<link rel="import" href="print_preview_vars_css.html">
<link rel="import" href="strings.html">
diff --git a/chromium/chrome/browser/resources/print_preview/icons.html b/chromium/chrome/browser/resources/print_preview/ui/icons.html
index 8cffcf206ad..1f5ce331dc9 100644
--- a/chromium/chrome/browser/resources/print_preview/icons.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/icons.html
@@ -7,20 +7,15 @@
<defs>
<!-- Custom svgs (namratakannan). -->
<g id="printer-shared" viewBox="0 0 106 96">
- <defs>
- <path d="M44 59H32v26h12v11H21.2V74.462H0V42.154C0 33.215 7.102 26 15.9 26h74.2c8.798 0 15.9 7.215 15.9 16.154V59H91.393A15.943 15.943 0 0 0 93 52c0-8.84-7.16-16-16-16s-16 7.16-16 16c0 2.51.578 4.886 1.607 7H44zM84 0H21v22h63V0z" id="a"></path>
- </defs>
- <g fill-rule="nonzero">
- <use xlink:href="#a"></use>
- <path d="M77 68c-9.679 0-29 6.253-29 18.667V96h58v-9.333C106 74.253 86.679 68 77 68zM77 64c6.63 0 12-5.37 12-12s-5.37-12-12-12-12 5.37-12 12 5.37 12 12 12z" fill="#4A93F9"></path>
- </g>
+ <path d="M44 59H32v26h12v11H21.2V74.462H0V42.154C0 33.215 7.102 26 15.9 26h74.2c8.798 0 15.9 7.215 15.9 16.154V59H91.393A15.943 15.943 0 0 0 93 52c0-8.84-7.16-16-16-16s-16 7.16-16 16c0 2.51.578 4.886 1.607 7H44zM84 0H21v22h63V0z"></path>
+ <path d="M77 68c-9.679 0-29 6.253-29 18.667V96h58v-9.333C106 74.253 86.679 68 77 68zM77 64c6.63 0 12-5.37 12-12s-5.37-12-12-12-12 5.37-12 12 5.37 12 12 12z" fill="#4A93F9"></path>
</g>
<g id="short-edge" viewBox="0 0 26 20" fill-rule="evenodd">
- <path d="M2 14v2h2v-2H2zm12 4v2h2v-2h-2zm4 0v2h2v-2h-2zm3.556-18H4.444C3.1 0 2 1.35 2 3v6h2V2h18v7h2V3c0-1.65-1.1-3-2.444-3zM24 18h-2v2c1.1 0 2-.9 2-2zM0 10v2h26v-2H0zm6 8v2h2v-2H6zm16-4v2h2v-2h-2zm-12 4v2h2v-2h-2zm-8 0c0 1.1.9 2 2 2v-2H2z" fill-rule="nonzero">
+ <path d="M2 14v2h2v-2H2zm12 4v2h2v-2h-2zm4 0v2h2v-2h-2zm3.556-18H4.444C3.1 0 2 1.35 2 3v6h2V2h18v7h2V3c0-1.65-1.1-3-2.444-3zM24 18h-2v2c1.1 0 2-.9 2-2zM0 10v2h26v-2H0zm6 8v2h2v-2H6zm16-4v2h2v-2h-2zm-12 4v2h2v-2h-2zm-8 0c0 1.1.9 2 2 2v-2H2z">
<path d="M29-6v32H-3V-6z">
</g>
<g id="long-edge" viewBox="0 0 23 22" fill-rule="evenodd">
- <path d="M17 20h2v-2h-2v2zm4-12h2V6h-2v2zM0 4v14c0 1.1 1.35 2 3 2h6v-2H2V4h7V2H3c-1.65 0-3 .9-3 2zm21-2v2h2c0-1.1-.9-2-2-2zM10 22h2V0h-2v22zm11-6h2v-2h-2v2zM17 4h2V2h-2v2zm-4 16h2v-2h-2v2zm0-16h2V2h-2v2zm8 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z" fill-rule="nonzero">
+ <path d="M17 20h2v-2h-2v2zm4-12h2V6h-2v2zM0 4v14c0 1.1 1.35 2 3 2h6v-2H2V4h7V2H3c-1.65 0-3 .9-3 2zm21-2v2h2c0-1.1-.9-2-2-2zM10 22h2V0h-2v22zm11-6h2v-2h-2v2zM17 4h2V2h-2v2zm-4 16h2v-2h-2v2zm0-16h2V2h-2v2zm8 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z">
<path d="M-5-5h32v32H-5z">
</g>
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 0e9dca3478f..97e8f1bfea2 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margin_control.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/margin_control.js
@@ -138,7 +138,7 @@ Polymer({
*/
convertPixelsToPts: function(pixels) {
let pts;
- const Orientation = print_preview.ticket_items.CustomMarginsOrientation;
+ const Orientation = print_preview.CustomMarginsOrientation;
if (this.side == Orientation.TOP) {
pts = pixels - this.translateTransform.y + RADIUS_PX;
pts /= this.scaleTransform;
@@ -253,7 +253,7 @@ Polymer({
return;
}
- const Orientation = print_preview.ticket_items.CustomMarginsOrientation;
+ const Orientation = print_preview.CustomMarginsOrientation;
let x = this.translateTransform.x;
let y = this.translateTransform.y;
let width = null;
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 b507fc864bb..c675756de45 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
@@ -7,15 +7,13 @@ cr.define('print_preview', function() {
'use strict';
/**
- * @const {!Map<!print_preview.ticket_items.CustomMarginsOrientation, string>}
+ * @const {!Map<!print_preview.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']
+ [print_preview.CustomMarginsOrientation.TOP, 'marginTop'],
+ [print_preview.CustomMarginsOrientation.RIGHT, 'marginRight'],
+ [print_preview.CustomMarginsOrientation.BOTTOM, 'marginBottom'],
+ [print_preview.CustomMarginsOrientation.LEFT, 'marginLeft']
]);
/** @const {number} */
@@ -87,16 +85,16 @@ cr.define('print_preview', function() {
},
/**
- * @private {!Array<!print_preview.ticket_items.CustomMarginsOrientation>}
+ * @private {!Array<!print_preview.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,
+ print_preview.CustomMarginsOrientation.TOP,
+ print_preview.CustomMarginsOrientation.RIGHT,
+ print_preview.CustomMarginsOrientation.BOTTOM,
+ print_preview.CustomMarginsOrientation.LEFT,
],
},
@@ -138,8 +136,7 @@ cr.define('print_preview', function() {
*/
computeAvailable_: function() {
return this.previewLoaded && !!this.clipSize_ &&
- this.getSettingValue('margins') ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM &&
+ this.getSettingValue('margins') == print_preview.MarginsType.CUSTOM &&
!!this.pageSize;
},
@@ -150,7 +147,7 @@ cr.define('print_preview', function() {
// custom margins were reset.
const newMargins = {};
for (const side of Object.values(
- print_preview.ticket_items.CustomMarginsOrientation)) {
+ print_preview.CustomMarginsOrientation)) {
const key = print_preview.MARGIN_KEY_MAP.get(side);
newMargins[key] = this.documentMargins.get(side);
}
@@ -187,11 +184,9 @@ cr.define('print_preview', function() {
this.resetMargins_ = true;
const marginsSetting = this.getSetting('margins');
- if (marginsSetting.value ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ if (marginsSetting.value == print_preview.MarginsType.CUSTOM) {
// Set the margins value to default first.
- this.setSetting(
- 'margins', print_preview.ticket_items.MarginsTypeValue.DEFAULT);
+ this.setSetting('margins', print_preview.MarginsType.DEFAULT);
}
// Reset custom margins so that the sticky value is not restored for the
// new paper size.
@@ -218,16 +213,14 @@ cr.define('print_preview', function() {
},
/**
- * @param {!print_preview.ticket_items.CustomMarginsOrientation} orientation
+ * @param {!print_preview.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;
+ return orientation == print_preview.CustomMarginsOrientation.TOP ||
+ orientation == print_preview.CustomMarginsOrientation.BOTTOM;
},
/**
@@ -241,8 +234,7 @@ cr.define('print_preview', function() {
*/
posInPixelsToPts_: function(control, posInPixels) {
const side =
- /** @type {print_preview.ticket_items.CustomMarginsOrientation} */ (
- control.side);
+ /** @type {print_preview.CustomMarginsOrientation} */ (control.side);
return this.clipAndRoundValue_(
side,
control.convertPixelsToPts(
@@ -349,7 +341,7 @@ cr.define('print_preview', function() {
const x = control.offsetLeft;
const y = control.offsetTop;
const isTopOrBottom = this.isTopOrBottom_(
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
+ /** @type {!print_preview.CustomMarginsOrientation} */ (
control.side));
const position = {};
// Extra padding, in px, to ensure the full textbox will be visible and
@@ -395,8 +387,7 @@ cr.define('print_preview', function() {
*/
setMargin_: function(side, marginValue) {
const marginSide =
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
- side);
+ /** @type {!print_preview.CustomMarginsOrientation} */ (side);
const oldMargins = /** @type {print_preview.MarginsSetting} */ (
this.getSettingValue('customMargins'));
const key = print_preview.MARGIN_KEY_MAP.get(marginSide);
@@ -416,12 +407,11 @@ cr.define('print_preview', function() {
*/
clipAndRoundValue_: function(side, value) {
const marginSide =
- /** @type {!print_preview.ticket_items.CustomMarginsOrientation} */ (
- side);
+ /** @type {!print_preview.CustomMarginsOrientation} */ (side);
if (value < 0) {
return 0;
}
- const Orientation = print_preview.ticket_items.CustomMarginsOrientation;
+ const Orientation = print_preview.CustomMarginsOrientation;
let limit = 0;
const margins = this.getSettingValue('customMargins');
if (marginSide == Orientation.TOP) {
@@ -482,10 +472,9 @@ cr.define('print_preview', function() {
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)) ?
+ this.dragging_ = this.isTopOrBottom_(
+ /** @type {print_preview.CustomMarginsOrientation} */
+ (control.side)) ?
'dragging-vertical' :
'dragging-horizontal';
this.listen(control, 'pointercancel', 'onPointerUp_');
diff --git a/chromium/chrome/browser/resources/print_preview/ui/margins_settings.html b/chromium/chrome/browser/resources/print_preview/ui/margins_settings.html
index f02aa28e304..a47ee58145f 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margins_settings.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/margins_settings.html
@@ -19,16 +19,19 @@
settings.pagesPerSheet.value)]]"
value="{{selectedValue::change}}">
<!-- The order of these options must match the natural order of their
- values, which come from
- print_preview.ticket_items.MarginsTypeValue. -->
- <option value="[[MarginsValue.DEFAULT]]" selected>
+ values, which come from print_preview.MarginsType. -->
+ <option value="[[MarginsTypeEnum.DEFAULT]]" selected>
$i18n{defaultMargins}
</option>
- <option value="[[MarginsValue.NO_MARGINS]]">$i18n{noMargins}</option>
- <option value="[[MarginsValue.MINIMUM]]">
+ <option value="[[MarginsTypeEnum.NO_MARGINS]]">
+ $i18n{noMargins}
+ </option>
+ <option value="[[MarginsTypeEnum.MINIMUM]]">
$i18n{minimumMargins}
</option>
- <option value="[[MarginsValue.CUSTOM]]">$i18n{customMargins}</option>
+ <option value="[[MarginsTypeEnum.CUSTOM]]">
+ $i18n{customMargins}
+ </option>
</select>
</div>
</print-preview-settings-section>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/margins_settings.js b/chromium/chrome/browser/resources/print_preview/ui/margins_settings.js
index 94732b721b3..cd4e0aec72a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/margins_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/margins_settings.js
@@ -11,14 +11,14 @@ Polymer({
disabled: Boolean,
/** Mirroring the enum so that it can be used from HTML bindings. */
- MarginsValue: Object,
+ MarginsTypeEnum: Object,
},
observers: ['onMarginsSettingChange_(settings.margins.value)'],
/** @override */
ready: function() {
- this.MarginsValue = print_preview.ticket_items.MarginsTypeValue;
+ this.MarginsTypeEnum = print_preview.MarginsType;
},
/**
@@ -27,8 +27,7 @@ Polymer({
*/
onMarginsSettingChange_: function(newValue) {
this.selectedValue =
- /** @type {!print_preview.ticket_items.MarginsTypeValue} */ (newValue)
- .toString();
+ /** @type {!print_preview.MarginsType} */ (newValue).toString();
},
/** @param {string} value The new select value. */
diff --git a/chromium/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js b/chromium/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
index d581eeedb72..9753375431a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
@@ -19,8 +19,7 @@ Polymer({
*/
onPagesPerSheetSettingChange_: function(newValue) {
this.selectedValue = /** @type {number} */ (newValue).toString();
- this.setSetting(
- 'margins', print_preview.ticket_items.MarginsTypeValue.DEFAULT);
+ this.setSetting('margins', print_preview.MarginsType.DEFAULT);
},
/** @param {string} value The new select value. */
diff --git a/chromium/chrome/browser/resources/print_preview/ui/pin_settings.js b/chromium/chrome/browser/resources/print_preview/ui/pin_settings.js
index e6c1c40346b..8e56e89d2c7 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/pin_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/pin_settings.js
@@ -66,7 +66,7 @@ Polymer({
/** @private */
onCollapseChanged_: function() {
if (this.pinEnabled_) {
- /** @type {!CrInputElement} */ (this.$.pinValue).inputElement.focus();
+ /** @type {!CrInputElement} */ (this.$.pinValue).focusInput();
}
},
diff --git a/chromium/chrome/browser/resources/print_preview/ui/preview_area.html b/chromium/chrome/browser/resources/print_preview/ui/preview_area.html
index ac0d828314d..2696ecfb2a9 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/preview_area.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/preview_area.html
@@ -10,6 +10,7 @@
<link rel="import" href="../dark_mode_behavior.html">
<link rel="import" href="../data/coordinate2d.html">
<link rel="import" href="../data/destination.html">
+<link rel="import" href="../data/destination_match.html">
<link rel="import" href="../data/margins.html">
<link rel="import" href="../data/model.html">
<link rel="import" href="../data/printable_area.html">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
index 71f038f3955..bee496891ac 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
@@ -529,13 +529,12 @@ Polymer({
*/
marginsValid_: function() {
const type = this.getSettingValue('margins');
- if (!Object.values(print_preview.ticket_items.MarginsTypeValue)
- .includes(type)) {
+ if (!Object.values(print_preview.MarginsType).includes(type)) {
// Unrecognized margins type.
return false;
}
- if (type !== print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ if (type !== print_preview.MarginsType.CUSTOM) {
return true;
}
@@ -567,11 +566,11 @@ Polymer({
// Margins
const newMarginsType = this.getSettingValue('margins');
if (newMarginsType !== lastTicket.marginsType &&
- newMarginsType !== print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ newMarginsType !== print_preview.MarginsType.CUSTOM) {
return true;
}
- if (newMarginsType === print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ if (newMarginsType === print_preview.MarginsType.CUSTOM) {
const customMargins =
/** @type {!print_preview.MarginsSetting} */ (
this.getSettingValue('customMargins'));
@@ -595,11 +594,10 @@ Polymer({
}
const customMarginsChanged =
- Object.values(print_preview.ticket_items.CustomMarginsOrientation)
- .some(side => {
- return this.margins.get(side) !==
- customMargins[print_preview.MARGIN_KEY_MAP.get(side)];
- });
+ Object.values(print_preview.CustomMarginsOrientation).some(side => {
+ return this.margins.get(side) !==
+ customMargins[print_preview.MARGIN_KEY_MAP.get(side)];
+ });
if (customMarginsChanged) {
return true;
}
@@ -608,28 +606,25 @@ Polymer({
// Simple settings: ranges, layout, header/footer, pages per sheet, fit to
// page, css background, selection only, rasterize, scaling, dpi
if (!areRangesEqual(
- /** @type {!Array<{from: number, to: number}>} */ (
- this.getSettingValue('ranges')),
- lastTicket.pageRange) ||
+ /** @type {!Array<{from: number, to: number}>} */
+ (this.getSettingValue('ranges')), lastTicket.pageRange) ||
this.getSettingValue('layout') !== lastTicket.landscape ||
this.getColorForTicket_() !== lastTicket.color ||
this.getSettingValue('headerFooter') !==
lastTicket.headerFooterEnabled ||
- this.getSettingValue('fitToPage') !== lastTicket.fitToPageEnabled ||
this.getSettingValue('cssBackground') !==
lastTicket.shouldPrintBackgrounds ||
this.getSettingValue('selectionOnly') !==
lastTicket.shouldPrintSelectionOnly ||
this.getSettingValue('rasterize') !== lastTicket.rasterizePDF ||
- this.getScaleFactorForTicket_() !== lastTicket.scaleFactor) {
+ this.isScalingChanged_(lastTicket)) {
return true;
}
// Pages per sheet. If margins are non-default, wait for the return to
// default margins to trigger a request.
if (this.getSettingValue('pagesPerSheet') !== lastTicket.pagesPerSheet &&
- this.getSettingValue('margins') ===
- print_preview.ticket_items.MarginsTypeValue.DEFAULT) {
+ this.getSettingValue('margins') === print_preview.MarginsType.DEFAULT) {
return true;
}
@@ -641,17 +636,13 @@ Polymer({
newValue.width_microns != lastTicket.mediaSize.width_microns ||
(this.destination.id !== lastTicket.deviceName &&
this.getSettingValue('margins') ===
- print_preview.ticket_items.MarginsTypeValue.MINIMUM)) {
+ print_preview.MarginsType.MINIMUM)) {
return true;
}
// Destination
- if (this.destination.isPrivet !== lastTicket.printWithPrivet ||
- this.destination.isExtension !== lastTicket.printWithExtension ||
- !this.destination.isLocal !== lastTicket.printWithCloudPrint ||
- (lastTicket.printToPDF &&
- this.destination.id !==
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF)) {
+ if (print_preview.getPrinterTypeForDestination(this.destination) !==
+ lastTicket.printerType) {
return true;
}
@@ -664,13 +655,48 @@ Polymer({
/** @type {boolean} */ (this.getSettingValue('color')));
},
- /** @return {number} Scale factor. */
+ /** @return {number} Scale factor for print ticket. */
getScaleFactorForTicket_: function() {
- return this.getSettingValue('customScaling') ?
+ return this.getSettingValue(this.getScalingSettingKey_()) ===
+ print_preview.ScalingType.CUSTOM ?
parseInt(this.getSettingValue('scaling'), 10) :
100;
},
+ /** @return {string} Appropriate key for the scaling type setting. */
+ getScalingSettingKey_: function() {
+ return this.getSetting('scalingTypePdf').available ? 'scalingTypePdf' :
+ 'scalingType';
+ },
+
+ /**
+ * @param {Object} lastTicket Last print ticket.
+ * @return {boolean} Whether new scaling settings update the previewed
+ * document.
+ */
+ isScalingChanged_: function(lastTicket) {
+ // Preview always updates if the scale factor is changed.
+ if (this.getScaleFactorForTicket_() !== lastTicket.scaleFactor) {
+ return true;
+ }
+
+ // If both scale factors and type match, no scaling change happened.
+ const scalingType = this.getSettingValue(this.getScalingSettingKey_());
+ if (scalingType === lastTicket.scalingType) {
+ return false;
+ }
+
+ // Scaling doesn't always change because of a scalingType change. Changing
+ // between custom scaling with a scale factor of 100 and default scaling
+ // makes no difference.
+ const defaultToCustom = scalingType === print_preview.ScalingType.DEFAULT &&
+ lastTicket.scalingType === print_preview.ScalingType.CUSTOM;
+ const customToDefault = scalingType === print_preview.ScalingType.CUSTOM &&
+ lastTicket.scalingType === print_preview.ScalingType.DEFAULT;
+
+ return !defaultToCustom && !customToDefault;
+ },
+
/**
* @param {string} dpiField The field in dpi to retrieve.
* @return {number} Field value.
@@ -705,8 +731,8 @@ Polymer({
isFirstRequest: this.inFlightRequestId_ == 0,
requestID: this.inFlightRequestId_,
previewModifiable: this.documentModifiable,
- fitToPageEnabled: this.getSettingValue('fitToPage'),
scaleFactor: this.getScaleFactorForTicket_(),
+ scalingType: this.getSettingValue(this.getScalingSettingKey_()),
shouldPrintBackgrounds: this.getSettingValue('cssBackground'),
shouldPrintSelectionOnly: this.getSettingValue('selectionOnly'),
// NOTE: Even though the remaining fields don't directly relate to the
@@ -720,11 +746,7 @@ Polymer({
duplex: this.getSettingValue('duplex') ?
print_preview.DuplexMode.LONG_EDGE :
print_preview.DuplexMode.SIMPLEX,
- printToPDF: this.destination.id ==
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
- printWithCloudPrint: !this.destination.isLocal,
- printWithPrivet: this.destination.isPrivet,
- printWithExtension: this.destination.isExtension,
+ printerType: print_preview.getPrinterTypeForDestination(this.destination),
rasterizePDF: this.getSettingValue('rasterize'),
};
@@ -733,8 +755,7 @@ Polymer({
ticket.cloudPrintID = this.destination.id;
}
- if (this.getSettingValue('margins') ==
- print_preview.ticket_items.MarginsTypeValue.CUSTOM) {
+ if (this.getSettingValue('margins') == print_preview.MarginsType.CUSTOM) {
ticket.marginsCustom = this.getSettingValue('customMargins');
}
this.lastTicket_ = ticket;
diff --git a/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.html b/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.html
index d4cd7a36b99..8da1200544a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.html
@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
+<link rel="import" href="../data/scaling.html">
<link rel="import" href="number_settings_section.html">
<link rel="import" href="print_preview_shared_css.html">
<link rel="import" href="select_behavior.html">
@@ -20,10 +21,12 @@
<option value="[[ScalingValue.DEFAULT]]">
$i18n{optionDefaultScaling}
</option>
- <option value="[[ScalingValue.FIT_TO_PAGE]]"
- hidden$="[[!settings.fitToPage.available]]">
+ <option value="[[ScalingValue.FIT_TO_PAGE]]" hidden$="[[!isPdf]]">
$i18n{optionFitToPage}
</option>
+ <option value="[[ScalingValue.FIT_TO_PAPER]]" hidden$="[[!isPdf]]">
+ $i18n{optionFitToPaper}
+ </option>
<option value="[[ScalingValue.CUSTOM]]">
$i18n{optionCustomScaling}
</option>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.js b/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.js
index 909562b33d3..500637a9ab2 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/scaling_settings.js
@@ -4,20 +4,10 @@
cr.exportPath('print_preview');
-/** @enum {number} */
-const ScalingValue = {
- DEFAULT: 0,
- FIT_TO_PAGE: 1,
- CUSTOM: 2,
-};
-
/*
- * When fit to page is available, the checkbox and input interact as follows:
- * 1. When checkbox is checked, the fit to page scaling value is displayed in
- * the input. The error message is cleared if it was present.
- * 2. When checkbox is unchecked, the most recent valid scale value is restored.
- * 3. If the input is modified while the checkbox is checked, the checkbox will
- * be unchecked automatically, regardless of the validity of the new value.
+ * Fit to page and fit to paper options will only be displayed for PDF
+ * documents. If the custom option is selected, an additional input field will
+ * appear to enter the custom scale factor.
*/
Polymer({
is: 'print-preview-scaling-settings',
@@ -30,6 +20,8 @@ Polymer({
observer: 'onDisabledChanged_',
},
+ isPdf: Boolean,
+
/** @private {string} */
currentValue_: {
type: String,
@@ -39,8 +31,8 @@ Polymer({
/** @private {boolean} */
customSelected_: {
type: Boolean,
- computed: 'computeCustomSelected_(settings.customScaling.*, ' +
- 'settings.fitToPage.*)',
+ computed: 'computeCustomSelected_(settingKey_, ' +
+ 'settings.scalingType.*, settings.scalingTypePdf.*)',
},
/** @private {boolean} */
@@ -52,14 +44,23 @@ Polymer({
value: false,
},
+ /** @private {string} */
+ settingKey_: {
+ type: String,
+ computed: 'computeSettingKey_(isPdf)',
+ },
+
/** Mirroring the enum so that it can be used from HTML bindings. */
- ScalingValue: Object,
+ ScalingValue: {
+ type: Object,
+ value: print_preview.ScalingType,
+ },
},
observers: [
- 'onFitToPageSettingChange_(settings.fitToPage.value)',
+ 'onScalingTypeSettingChanged_(settingKey_, settings.scalingType.value, ' +
+ 'settings.scalingTypePdf.value)',
'onScalingSettingChanged_(settings.scaling.value)',
- 'onCustomScalingSettingChanged_(settings.customScaling.value)',
],
/** @private {string} */
@@ -81,28 +82,26 @@ Polymer({
*/
userSelectedCustomScaling_: false,
- /** @override */
- ready: function() {
- this.ScalingValue = ScalingValue;
- },
-
onProcessSelectChange: function(value) {
- if (value === ScalingValue.FIT_TO_PAGE.toString()) {
- this.setSetting('fitToPage', true);
- return;
- }
-
- const fitToPageAvailable = this.getSetting('fitToPage').available;
- if (fitToPageAvailable) {
- this.setSetting('fitToPage', false);
- }
- const isCustom = value === ScalingValue.CUSTOM.toString();
+ const isCustom = value === print_preview.ScalingType.CUSTOM.toString();
if (isCustom && !this.customScalingSettingSet_) {
this.userSelectedCustomScaling_ = true;
} else {
this.customScalingSettingSet_ = false;
}
- this.setSetting('customScaling', isCustom);
+
+ const valueAsNumber = parseInt(value, 10);
+ if (isCustom || value === print_preview.ScalingType.DEFAULT.toString()) {
+ this.setSetting('scalingType', valueAsNumber);
+ }
+ if (this.isPdf ||
+ this.getSetting('scalingTypePdf').value ===
+ print_preview.ScalingType.DEFAULT ||
+ this.getSetting('scalingTypePdf').value ===
+ print_preview.ScalingType.CUSTOM) {
+ this.setSetting('scalingTypePdf', valueAsNumber);
+ }
+
if (isCustom) {
this.setSetting('scaling', this.currentValue_);
}
@@ -117,48 +116,35 @@ Polymer({
}
},
- /** @private */
- onFitToPageSettingChange_: function() {
- if (!this.getSettingValue('fitToPage') ||
- !this.getSetting('fitToPage').available) {
- return;
- }
-
- this.updateScalingToValid_();
- this.selectedValue = ScalingValue.FIT_TO_PAGE.toString();
+ /**
+ * Updates the input string when scaling setting is set.
+ * @private
+ */
+ onScalingSettingChanged_: function() {
+ const value = /** @type {string} */ (this.getSetting('scaling').value);
+ this.lastValidScaling_ = value;
+ this.currentValue_ = value;
},
/** @private */
- onCustomScalingSettingChanged_: function() {
- if (this.getSettingValue('fitToPage') &&
- this.getSetting('fitToPage').available) {
+ onScalingTypeSettingChanged_: function() {
+ if (!this.settingKey_) {
return;
}
- const isCustom =
- /** @type {boolean} */ (this.getSetting('customScaling').value);
- if (!isCustom) {
+ const value = /** @type {!print_preview.ScalingType} */
+ (this.getSettingValue(this.settingKey_));
+ if (value !== print_preview.ScalingType.CUSTOM) {
this.updateScalingToValid_();
} else {
this.customScalingSettingSet_ = true;
}
- this.selectedValue = isCustom ? ScalingValue.CUSTOM.toString() :
- ScalingValue.DEFAULT.toString();
- },
-
- /**
- * Updates the input string when scaling setting is set.
- * @private
- */
- onScalingSettingChanged_: function() {
- const value = /** @type {string} */ (this.getSetting('scaling').value);
- this.lastValidScaling_ = value;
- this.currentValue_ = value;
+ this.selectedValue = value.toString();
},
/**
- * Updates scaling and fit to page settings based on the validity and current
- * value of the scaling input.
+ * Updates scaling settings based on the validity and current value of the
+ * scaling input.
* @private
*/
onInputChanged_: function() {
@@ -188,9 +174,17 @@ Polymer({
* @private
*/
computeCustomSelected_: function() {
- return /** @type {boolean} */ (this.getSettingValue('customScaling')) &&
- (!this.getSetting('fitToPage').available ||
- !(/** @type {boolean} */ (this.getSettingValue('fitToPage'))));
+ return !!this.settingKey_ &&
+ this.getSettingValue(this.settingKey_) ===
+ print_preview.ScalingType.CUSTOM;
+ },
+
+ /**
+ * @return {string} The key of the appropriate scaling setting.
+ * @private
+ */
+ computeSettingKey_: function() {
+ return this.isPdf ? 'scalingTypePdf' : 'scalingType';
},
/** @private */
diff --git a/chromium/chrome/browser/resources/print_preview/ui/sidebar.html b/chromium/chrome/browser/resources/print_preview/ui/sidebar.html
index 7e5739246aa..7fffd00a38c 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/sidebar.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/sidebar.html
@@ -48,6 +48,11 @@
flex-direction: column;
}
+ :host([new-print-preview-layout]) {
+ border-inline-end: none;
+ border-inline-start: var(--print-preview-settings-border);
+ }
+
@media (prefers-color-scheme: dark) {
:host {
background-color: rgba(255, 255, 255, .04);
@@ -163,7 +168,7 @@
hidden$="[[!settings.dpi.available]]" class="settings-section">
</print-preview-dpi-settings>
<print-preview-scaling-settings settings="[[settings]]"
- disabled="[[controlsDisabled_]]"
+ disabled="[[controlsDisabled_]]" is-pdf="[[isPdf]]"
hidden$="[[!settings.scaling.available]]"
class="settings-section">
</print-preview-scaling-settings>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/sidebar.js b/chromium/chrome/browser/resources/print_preview/ui/sidebar.js
index 687539f8323..fe77e9d7c44 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/sidebar.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/sidebar.js
@@ -47,6 +47,8 @@ Polymer({
notify: true,
},
+ isPdf: Boolean,
+
newPrintPreviewLayout: {
type: Boolean,
reflectToAttribute: true,
diff --git a/chromium/chrome/browser/resources/quota_internals/OWNERS b/chromium/chrome/browser/resources/quota_internals/OWNERS
index 597882cfcde..84d5cb66e1c 100644
--- a/chromium/chrome/browser/resources/quota_internals/OWNERS
+++ b/chromium/chrome/browser/resources/quota_internals/OWNERS
@@ -1 +1,4 @@
-tzik@chromium.org \ No newline at end of file
+file://storage/browser/quota/OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>Quota
diff --git a/chromium/chrome/browser/resources/quota_internals/event_handler.js b/chromium/chrome/browser/resources/quota_internals/event_handler.js
index ef5d3c11bc4..e4594b73cab 100644
--- a/chromium/chrome/browser/resources/quota_internals/event_handler.js
+++ b/chromium/chrome/browser/resources/quota_internals/event_handler.js
@@ -378,7 +378,7 @@ function handleStatistics(event) {
for (const key in data) {
let entry = statistics[key];
if (!entry) {
- entry = cr.doc.createElement('tr');
+ entry = document.createElement('tr');
$('stat-entries').appendChild(entry);
statistics[key] = entry;
}
@@ -417,7 +417,7 @@ function updateDescription() {
const normalize = keyAndLabel[i][2] || stringToText_;
- const row = cr.doc.createElement('tr');
+ const row = document.createElement('tr');
row.innerHTML = '<td>' + label + '</td>' +
'<td>' + normalize(entry) + '</td>';
tbody.appendChild(row);
@@ -493,5 +493,5 @@ function onLoad() {
$('dump-button').addEventListener('click', dump, false);
}
-cr.doc.addEventListener('DOMContentLoaded', onLoad, false);
+document.addEventListener('DOMContentLoaded', onLoad, false);
})();
diff --git a/chromium/chrome/browser/resources/quota_internals/message_dispatcher.js b/chromium/chrome/browser/resources/quota_internals/message_dispatcher.js
index b1024b6ba38..a387094e4b9 100644
--- a/chromium/chrome/browser/resources/quota_internals/message_dispatcher.js
+++ b/chromium/chrome/browser/resources/quota_internals/message_dispatcher.js
@@ -63,7 +63,7 @@ cr.define('cr.quota', function() {
break;
}
if (target) {
- const event = cr.doc.createEvent('CustomEvent');
+ const event = document.createEvent('CustomEvent');
event.initCustomEvent('update', false, false, detail);
target.dispatchEvent(event);
}
diff --git a/chromium/chrome/browser/resources/reset_password/BUILD.gn b/chromium/chrome/browser/resources/reset_password/BUILD.gn
index d464dd90c25..322a3a80274 100644
--- a/chromium/chrome/browser/resources/reset_password/BUILD.gn
+++ b/chromium/chrome/browser/resources/reset_password/BUILD.gn
@@ -13,7 +13,6 @@ js_type_check("closure_compile") {
js_library("reset_password") {
deps = [
"//chrome/browser/ui/webui/reset_password:mojo_bindings_js_library_for_compile",
- "//ui/webui/resources/js:assert",
- "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:util.m",
]
}
diff --git a/chromium/chrome/browser/resources/reset_password/reset_password.html b/chromium/chrome/browser/resources/reset_password/reset_password.html
index fa9d646c670..a16273ef371 100644
--- a/chromium/chrome/browser/resources/reset_password/reset_password.html
+++ b/chromium/chrome/browser/resources/reset_password/reset_password.html
@@ -5,14 +5,7 @@
<meta name="viewport" content="width=device-width">
<title>$i18n{title}</title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
- <link rel="import" href="chrome://resources/html/polymer.html">
- <link rel="import" href="chrome://resources/cr_elements/icons.html">
- <link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
- <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
- <script src="chrome://resources/js/util.js"></script>
- <script src="reset_password.mojom-lite.js"></script>
- <script src="reset_password.js"></script>
+ <script type="module" src="reset_password.js"></script>
<style>
html {
font-size: 125%;
diff --git a/chromium/chrome/browser/resources/reset_password/reset_password.js b/chromium/chrome/browser/resources/reset_password/reset_password.js
index b08c7c32875..886c65c4169 100644
--- a/chromium/chrome/browser/resources/reset_password/reset_password.js
+++ b/chromium/chrome/browser/resources/reset_password/reset_password.js
@@ -2,16 +2,20 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-'use strict';
-/**
- * JavaScript for reset_password.html, served from chrome://reset-password/.
- */
-(function() {
+// Javascript for chrome://reset-password/ WebUI page.
+
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
+import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import './reset_password.mojom-lite.js';
+
+import {$} from 'chrome://resources/js/util.m.js';
/** @type {mojom.ResetPasswordHandlerRemote} */
let pageHandler;
-function initialize() {
+document.addEventListener('DOMContentLoaded', function() {
pageHandler = mojom.ResetPasswordHandler.getRemote();
/** @type {?HTMLElement} */
@@ -19,7 +23,4 @@ function initialize() {
resetPasswordButton.addEventListener('click', function() {
pageHandler.handlePasswordReset();
});
-}
-
-document.addEventListener('DOMContentLoaded', initialize);
-})();
+});
diff --git a/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py b/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py
index 012844a2057..e7eae89d2bf 100644
--- a/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py
+++ b/chromium/chrome/browser/resources/safety_tips/PRESUBMIT.py
@@ -24,18 +24,13 @@ def CheckVersionUpdatedInProto(input_api, output_api):
return []
contents = safety_tips_proto[0].ChangedContents()
- # Must not have any changes containing flagged_page:
- if ContainsLine(contents, 'flagged_page:'):
+ # Must not have any changes containing flagged_page or allowed_pattern:
+ if (ContainsLine(contents, 'flagged_page:') or
+ ContainsLine(contents, 'allowed_pattern:')):
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
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 e4ec99a4e3e..75f7e34655a 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
@@ -43,14 +43,22 @@ class SafetyTipsProtoGenerator(BinaryProtoGenerator):
def ValidatePb(self, opts, pb):
assert pb.version_id > 0
+
for flagged_page in pb.flagged_page:
assert flagged_page.pattern
assert flagged_page.type != safety_tips_pb2.FlaggedPage.UNKNOWN
- flagged_patterns = [page.pattern for page in pb.flagged_page]
+ for allowed_pattern in pb.allowed_pattern:
+ assert allowed_pattern.pattern
+
+ flagged_patterns = [p.pattern for p in pb.flagged_page]
assert sorted(flagged_patterns) == flagged_patterns, (
"Please sort flagged_page entries by pattern.")
+ allowed_patterns = [p.pattern for p in pb.allowed_pattern]
+ assert sorted(allowed_patterns) == allowed_patterns, (
+ "Please sort allowed_pattern 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/safety_tips.asciipb b/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
index 64b7f997870..a1536bd796d 100644
--- a/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
+++ b/chromium/chrome/browser/resources/safety_tips/safety_tips.asciipb
@@ -8,13 +8,20 @@
# locally, generate and push the protobuffer to the storage bucket but do not
# check in the changes.
-version_id: 4
+version_id: 5
# See chrome/browser/lookalikes/safety_tips.proto for the full format.
-# These entries must be sorted alphabetically by pattern.
+# flagged_page entries must be sorted alphabetically by pattern.
# Example entry:
# flagged_page {
-# pattern: "example.test/test-path-for-safety-tips/test.html"
-# type: BAD_REP
-#}
+# pattern: "bad.test/test-path-for-safety-tips/test.html"
+# type: BAD_REP
+# }
+
+# A page that's marked to not show a UI for any heuristic (including lookalike
+# or edit distance).
+# allowed_pattern entries must be sorted alphabetically by pattern.
+# allowed_pattern: {
+# pattern: "good.test/some/path.html"
+# }
diff --git a/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn b/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn
new file mode 100644
index 00000000000..121a5e8f54e
--- /dev/null
+++ b/chromium/chrome/browser/resources/sandbox_internals/BUILD.gn
@@ -0,0 +1,38 @@
+# 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") {
+ if (is_win) {
+ deps = [
+ ":sandbox_internals_win",
+ ]
+ }
+ if (is_android || is_linux) {
+ deps = [
+ ":sandbox_internals",
+ ]
+ }
+}
+
+js_library("sandbox_internals") {
+ # Android & Linux both need _externs for type checks as they share a js file.
+ deps = [
+ ":sandbox_android_externs",
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:load_time_data",
+ "//ui/webui/resources/js:util",
+ ]
+}
+
+js_library("sandbox_android_externs") {
+}
+
+js_library("sandbox_internals_win") {
+ deps = [
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:util",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/sandbox_internals/OWNERS b/chromium/chrome/browser/resources/sandbox_internals/OWNERS
new file mode 100644
index 00000000000..058ee25caec
--- /dev/null
+++ b/chromium/chrome/browser/resources/sandbox_internals/OWNERS
@@ -0,0 +1,3 @@
+file://sandbox/OWNERS
+# COMPONENT: Internals>Sandbox
+# TEAM: security-dev@chromium.org
diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_android_externs.js b/chromium/chrome/browser/resources/sandbox_internals/sandbox_android_externs.js
new file mode 100644
index 00000000000..a6f170cf1c3
--- /dev/null
+++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_android_externs.js
@@ -0,0 +1,9 @@
+// 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.
+
+/**
+ * This function is only exposed to the Android chrome://sandbox webui.
+ * @param {!function(!AndroidSandboxStatus)=} callback
+ */
+chrome.getAndroidSandboxStatus = function(callback) {};
diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html
index 7f4816b4bbe..c5c269faa9c 100644
--- a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html
+++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.html
@@ -30,10 +30,13 @@
}
</style>
<script src="chrome://resources/js/cr.js"></script>
- <if expr="not is_android">
+<if expr="is_linux">
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://sandbox/strings.js"></script>
- </if>
+</if>
+<if expr="is_win">
+ <script src="chrome://resources/js/promise_resolver.js"></script>
+</if>
<script src="chrome://resources/js/util.js"></script>
<script src="sandbox_internals.js"></script>
</head>
@@ -42,7 +45,9 @@
<table id="sandbox-status">
</table>
-
<p id="evaluation"></p>
+<if expr="is_win">
+ <pre id="raw-info"></pre>
+</if>
</body>
</html>
diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.js b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.js
index ab15fb20587..dbee2331bc4 100644
--- a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.js
+++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals.js
@@ -2,6 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/**
+ * @typedef {{
+ * seccompStatus: number,
+ * pid: string,
+ * uid: string,
+ * secontext: string,
+ * procStatus: string,
+ * androidBuildId: string
+ * }}
+ */
+let AndroidSandboxStatus;
+
(function() {
/**
* CSS classes for different statuses.
@@ -22,10 +34,10 @@ const StatusClass = {
* @return {Element} The newly added TR.
*/
function addStatusRow(name, value, cssClass) {
- const row = cr.doc.createElement('tr');
+ const row = document.createElement('tr');
- const nameCol = row.appendChild(cr.doc.createElement('td'));
- const valueCol = row.appendChild(cr.doc.createElement('td'));
+ const nameCol = row.appendChild(document.createElement('td'));
+ const valueCol = row.appendChild(document.createElement('td'));
nameCol.textContent = name;
valueCol.textContent = value;
@@ -52,7 +64,7 @@ function addGoodBadRow(name, result) {
/**
* Reports the overall sandbox status evaluation message.
- * @param {boolean}
+ * @param {boolean} result
*/
function setEvaluation(result) {
const message = result ? 'You are adequately sandboxed.' :
diff --git a/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js
new file mode 100644
index 00000000000..100b04e20f6
--- /dev/null
+++ b/chromium/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js
@@ -0,0 +1,108 @@
+// 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 {{
+ * processId: number,
+ * processType: string,
+ * name: string,
+ * metricsName: string
+ * }}
+ */
+let BrowserHostProcess;
+
+/**
+ * @typedef {{
+ * processId: number
+ * }}
+ */
+let RendererHostProcess;
+
+/**
+ * This may have additional fields displayed in the JSON output.
+ * See //sandbox/win/src/sandbox_constants.cc for keys in policy.
+ * @typedef {{
+ * processIds: !Array<number>,
+ * lockdownLevel: string,
+ * desiredIntegrityLevel: string,
+ * platformMitigations: string
+ * }}
+ */
+let PolicyDiagnostic;
+
+/**
+ * @typedef {{
+ * browser: !Array<!BrowserHostProcess>,
+ * renderer: !Array<!RendererHostProcess>,
+ * policies: !Array<!PolicyDiagnostic>
+ * }}
+ */
+let SandboxDiagnostics;
+
+/**
+ * Adds a row to the sandbox-status table.
+ * @param {!Array<string>} args
+ */
+function addRow(args) {
+ const row = document.createElement('tr');
+ for (const text of args) {
+ const col = row.appendChild(document.createElement('td'));
+ col.textContent = text;
+ }
+ $('sandbox-status').appendChild(row);
+}
+
+/**
+ * Adds policy information for a process to the sandbox-status table.
+ * @param {number} pid
+ * @param {string} type
+ * @param {string} name
+ * @param {PolicyDiagnostic} policy
+ */
+function addRowForProcess(pid, type, name, policy) {
+ if (policy) {
+ addRow([
+ pid, type, name, policy.lockdownLevel, policy.desiredIntegrityLevel,
+ policy.platformMitigations
+ ]);
+ } else {
+ addRow([pid, type, name, 'Not Sandboxed', '', '']);
+ }
+}
+
+/** @param {!SandboxDiagnostics} results */
+function onGetSandboxDiagnostics(results) {
+ // Make it easy to look up policies.
+ /** @type {!Map<number,!PolicyDiagnostic>} */
+ const policies = new Map();
+ for (const policy of results.policies) {
+ // At present only one process per TargetPolicy object.
+ const pid = policy.processIds[0];
+ policies.set(pid, policy);
+ }
+
+ // Titles.
+ addRow(['Process', 'Type', 'Name', 'Sandbox', 'Intregity', 'Mitigations']);
+
+ // Browser Processes.
+ for (const process of results.browser) {
+ const pid = process.processId;
+ const name = process.name || process.metricsName;
+ addRowForProcess(pid, process.processType, name, policies.get(pid));
+ }
+
+ // Renderer Processes.
+ for (const process of results.renderer) {
+ const pid = process.processId;
+ addRowForProcess(pid, 'Renderer', '', policies.get(pid));
+ }
+
+ // Raw Diagnostics.
+ $('raw-info').textContent =
+ 'policies: ' + JSON.stringify(results.policies, null, 2);
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ cr.sendWithPromise('requestSandboxDiagnostics').then(onGetSandboxDiagnostics);
+});
diff --git a/chromium/chrome/browser/resources/settings/BUILD.gn b/chromium/chrome/browser/resources/settings/BUILD.gn
index 4ba0dd05e72..beba5017d3b 100644
--- a/chromium/chrome/browser/resources/settings/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/BUILD.gn
@@ -180,5 +180,5 @@ js_library("search_settings") {
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js:search_highlight_utils",
]
- externs_list = [ "$externs_path/pending.js" ]
+ externs_list = [ "$externs_path/pending_polymer.js" ]
}
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 078fc8f2161..86bd1584a0c 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -22,10 +22,19 @@
<settings-animated-pages id="pages" current-route="{{currentRoute}}"
section="a11y" focus-config="[[focusConfig_]]">
<div route-path="default">
- <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}"
- on-click="onCaptionsClick_" external$="[[captionSettingsOpensExternally_]]">
+<if expr="chromeos">
+ <cr-link-row class="hr" id="subpage-trigger"
+ label="$i18n{manageAccessibilityFeatures}"
+ on-click="onManageSystemAccessibilityFeaturesTap_"
+ sub-label="$i18n{moreFeaturesLinkDescription}"
+ hidden="[[showOsSettings_]]" external>
</cr-link-row>
+</if>
<if expr="not chromeos">
+ <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}"
+ on-click="onCaptionsClick_"
+ external$="[[captionSettingsOpensExternally_]]">
+ </cr-link-row>
<settings-toggle-button
id="a11yImageLabels"
hidden$="[[!showAccessibilityLabelsSetting_]]"
@@ -36,7 +45,7 @@
</settings-toggle-button>
</if>
<if expr="chromeos">
- <template is="dom-if" if="[[pageVisibility.webstoreLink]]">
+ <template is="dom-if" if="[[showOsSettings_]]">
<settings-toggle-button
id="a11yImageLabels"
hidden$="[[!showAccessibilityLabelsSetting_]]"
@@ -58,7 +67,7 @@
</if>
<cr-link-row class="hr" label="$i18n{moreFeaturesLink}"
on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}"
- hidden="[[pageVisibility.webstoreLink]]" external>
+ hidden="[[showOsSettings_]]" external>
</cr-link-row>
</div>
<if expr="not is_macosx">
@@ -73,7 +82,17 @@
</template>
</if>
<if expr="chromeos">
- <template is="dom-if" if="[[pageVisibility.webstoreLink]]">
+ <template is="dom-if" if="[[showCaptionSettings_]]">
+ <template is="dom-if" route-path="/manageAccessibility/captions">
+ <settings-subpage
+ associated-control="[[$$('#subpage-trigger')]]"
+ page-title="$i18n{captionsTitle}">
+ <settings-captions prefs="{{prefs}}">
+ </settings-captions>
+ </settings-subpage>
+ </template>
+ </template>
+ <template is="dom-if" if="[[showOsSettings_]]">
<template is="dom-if" route-path="/manageAccessibility">
<settings-subpage
associated-control="[[$$('#subpage-trigger')]]"
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 31045680975..6b24c8fa880 100644
--- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
+++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -68,6 +68,17 @@ Polymer({
},
/**
+ * Whether to show OS settings.
+ * @private {boolean}
+ */
+ showOsSettings_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean('showOSSettings');
+ },
+ },
+
+ /**
* Whether the caption settings link opens externally.
* @private {boolean}
*/
@@ -86,20 +97,6 @@ Polymer({
return opensExternally;
},
},
-
- // <if expr="chromeos">
- /**
- * Whether to show experimental accessibility features.
- * Only used in Chrome OS.
- * @private {boolean}
- */
- showExperimentalFeatures_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('showExperimentalA11yFeatures');
- },
- },
- // </if>
},
/** @override */
@@ -136,6 +133,11 @@ Polymer({
onManageAccessibilityFeaturesTap_: function() {
settings.navigateTo(settings.routes.MANAGE_ACCESSIBILITY);
},
+
+ /** @private */
+ onManageSystemAccessibilityFeaturesTap_: function() {
+ window.location.href = 'chrome://os-settings/manageAccessibility';
+ },
// </if>
/** private */
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 7f290fc3df3..ccc488cb561 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
@@ -80,31 +80,35 @@
label="$i18n{screenMagnifierLabel}"
disabled="[[prefs.ash.docked_magnifier.enabled.value]]">
</settings-toggle-button>
- <div class="settings-box continuation">
- <div class="start sub-item settings-box-text">
- $i18n{screenMagnifierZoomLabel}
+ <template is="dom-if" if="[[prefs.settings.a11y.screen_magnifier.value]]">
+ <div class="settings-box continuation">
+ <div class="start sub-item settings-box-text">
+ $i18n{screenMagnifierZoomLabel}
+ </div>
+ <settings-dropdown-menu label="$i18n{screenMagnifierZoomLabel}"
+ pref="{{prefs.settings.a11y.screen_magnifier_scale}}"
+ menu-options="[[screenMagnifierZoomOptions_]]"
+ disabled="[[!prefs.settings.a11y.screen_magnifier.value]]">
+ </settings-dropdown-menu>
</div>
- <settings-dropdown-menu label="$i18n{screenMagnifierZoomLabel}"
- pref="{{prefs.settings.a11y.screen_magnifier_scale}}"
- menu-options="[[screenMagnifierZoomOptions_]]"
- disabled="[[!prefs.settings.a11y.screen_magnifier.value]]">
- </settings-dropdown-menu>
- </div>
+ </template>
<settings-toggle-button
pref="{{prefs.ash.docked_magnifier.enabled}}"
label="$i18n{dockedMagnifierLabel}"
disabled="[[prefs.settings.a11y.screen_magnifier.value]]">
</settings-toggle-button>
- <div class="settings-box continuation">
- <div class="start sub-item settings-box-text">
- $i18n{dockedMagnifierZoomLabel}
+ <template is="dom-if" if="[[prefs.ash.docked_magnifier.enabled.value]]">
+ <div class="settings-box continuation">
+ <div class="start sub-item settings-box-text">
+ $i18n{dockedMagnifierZoomLabel}
+ </div>
+ <settings-dropdown-menu label="$i18n{dockedMagnifierZoomLabel}"
+ pref="{{prefs.ash.docked_magnifier.scale}}"
+ menu-options="[[screenMagnifierZoomOptions_]]"
+ disabled="[[!prefs.ash.docked_magnifier.enabled.value]]">
+ </settings-dropdown-menu>
</div>
- <settings-dropdown-menu label="$i18n{dockedMagnifierZoomLabel}"
- pref="{{prefs.ash.docked_magnifier.scale}}"
- menu-options="[[screenMagnifierZoomOptions_]]"
- disabled="[[!prefs.ash.docked_magnifier.enabled.value]]">
- </settings-dropdown-menu>
- </div>
+ </template>
<cr-link-row class="hr" label="$i18n{displaySettingsTitle}"
on-click="onDisplayTap_" sub-label="$i18n{displaySettingsDescription}"
embedded></cr-link-row>
@@ -218,12 +222,14 @@
on-click="onMouseTap_" sub-label="$i18n{mouseSettingsDescription}"
embedded></cr-link-row>
- <h2>$i18n{audioHeading}</h2>
- <settings-toggle-button class="first"
+ <h2>$i18n{audioAndCaptionsHeading}</h2>
+ <cr-link-row class="first" label="$i18n{captionsTitle}"
+ on-click="onCaptionsClick_"></cr-link-row>
+ <settings-toggle-button
pref="{{prefs.settings.a11y.mono_audio}}"
label="$i18n{monoAudioLabel}">
</settings-toggle-button>
- <settings-toggle-button id="startupSoundEnabled" class="first"
+ <settings-toggle-button id="startupSoundEnabled"
pref=" "
on-change="toggleStartupSoundEnabled_"
label="$i18n{startupSoundLabel}">
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 5365829d90f..8828b4fee1a 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
@@ -98,17 +98,6 @@ Polymer({
},
},
- /**
- * Whether to show experimental accessibility features.
- * @private {boolean}
- */
- showExperimentalFeatures_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('showExperimentalA11yFeatures');
- },
- },
-
showExperimentalSwitchAccess_: {
type: Boolean,
value: function() {
@@ -206,6 +195,11 @@ Polymer({
},
/** @private */
+ onCaptionsClick_: function() {
+ settings.navigateTo(settings.routes.MANAGE_CAPTION_SETTINGS);
+ },
+
+ /** @private */
onSelectToSpeakSettingsTap_: function() {
chrome.send('showSelectToSpeakSettings');
},
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 d4781a4d1b7..cdb845116be 100644
--- a/chromium/chrome/browser/resources/settings/about_page/about_page.js
+++ b/chromium/chrome/browser/resources/settings/about_page/about_page.js
@@ -233,8 +233,8 @@ Polymer({
this.regulatoryInfo_ = info;
});
- this.aboutBrowserProxy_.getHasEndOfLife().then(result => {
- this.hasEndOfLife_ = result;
+ this.aboutBrowserProxy_.getEndOfLifeInfo().then(result => {
+ this.hasEndOfLife_ = !!result.hasEndOfLife;
});
this.aboutBrowserProxy_.getEnabledReleaseNotes().then(result => {
diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
index d1f1373396e..1d5eeb7273d 100644
--- a/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
@@ -27,20 +27,19 @@ let ChannelInfo;
/**
* @typedef {{
- * arcVersion: string,
- * osFirmware: string,
- * osVersion: string,
+ * version: (string|undefined),
+ * size: (string|undefined),
* }}
*/
-let VersionInfo;
+let AboutPageUpdateInfo;
/**
* @typedef {{
- * version: (string|undefined),
- * size: (string|undefined),
+ * hasEndOfLife: (boolean|undefined),
+ * eolMessageWithMonthAndYear: (string|undefined),
* }}
*/
-let AboutPageUpdateInfo;
+let EndOfLifeInfo;
/**
* Enumeration of all possible browser channels.
@@ -200,18 +199,15 @@ cr.define('settings', function() {
/** @return {!Promise<!ChannelInfo>} */
getChannelInfo() {}
- /** @return {!Promise<!VersionInfo>} */
- getVersionInfo() {}
-
/** @return {!Promise<?RegulatoryInfo>} */
getRegulatoryInfo() {}
/**
* Checks if the device has reached end-of-life status and will no longer
* receive updates.
- * @return {!Promise<boolean>}
+ * @return {!Promise<!EndOfLifeInfo>}
*/
- getHasEndOfLife() {}
+ getEndOfLifeInfo() {}
/**
* Request TPM firmware update status from the browser. It results in one or
@@ -309,18 +305,13 @@ cr.define('settings', function() {
}
/** @override */
- getVersionInfo() {
- return cr.sendWithPromise('getVersionInfo');
- }
-
- /** @override */
getRegulatoryInfo() {
return cr.sendWithPromise('getRegulatoryInfo');
}
/** @override */
- getHasEndOfLife() {
- return cr.sendWithPromise('getHasEndOfLife');
+ getEndOfLifeInfo() {
+ return cr.sendWithPromise('getEndOfLifeInfo');
}
/** @override */
diff --git a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
index a974334455c..78ac464caad 100644
--- a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
+++ b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -19,7 +19,7 @@
<div slot="title">$i18n{aboutChangeChannel}</div>
<div slot="body">
<!-- TODO(dbeam): this can be policy-controlled. Show this in the UI.
- https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel
+ https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ChromeOsReleaseChannel
-->
<cr-radio-group on-selected-changed="onChannelSelectionChanged_">
<cr-radio-button name="[[browserChannelEnum_.STABLE]]">
diff --git a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html
index 2369486bc71..fa1ae5f812e 100644
--- a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html
+++ b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html
@@ -24,15 +24,6 @@
width: 100%;
}
</style>
- <div class="settings-box two-line single-column">
- <div>$i18n{aboutPlatformLabel}</div>
- <div class="secondary" id="osVersion">[[versionInfo_.osVersion]]</div>
- </div>
- <div class="settings-box two-line single-column"
- hidden$="[[!shouldShowVersion_(versionInfo_.osFirmware)]]">
- <div>$i18n{aboutFirmwareLabel}</div>
- <div class="secondary" id="osFirmware">[[versionInfo_.osFirmware]]</div>
- </div>
<div class="settings-box two-line">
<div class="start">
<div>$i18n{aboutChannelLabel}</div>
@@ -57,29 +48,17 @@
</settings-channel-switcher-dialog>
</template>
</div>
- <div class="settings-box two-line single-column"
- hidden$="[[!shouldShowVersion_(versionInfo_.arcVersion)]]">
- <div>$i18n{aboutArcVersionLabel}</div>
- <div class="secondary" id="arcVersion">[[versionInfo_.arcVersion]]</div>
- </div>
- <div class="settings-box two-line single-column">
- <div>V8</div>
- <div class="secondary">$i18n{aboutJsEngineVersion}</div>
- </div>
- <div class="settings-box two-line single-column">
- <div>$i18n{aboutUserAgentLabel}</div>
- <div class="secondary">$i18n{aboutUserAgent}</div>
- </div>
- <div class="settings-box two-line single-column">
- <div>$i18n{aboutCommandLineLabel}</div>
- <div id="command-line" class="secondary">
- [[i18n('aboutCommandLine')]]
+ <div id="endOfLifeSectionContainer"
+ class="settings-box two-line single-column"
+ hidden="[[!eolMessageWithMonthAndYear]]">
+ <div>$i18n{aboutEndOfLifeTitle}</div>
+ <div class="secondary" inner-h-t-m-l="[[eolMessageWithMonthAndYear]]">
</div>
</div>
- <div class="settings-box two-line single-column">
- <div>$i18n{aboutBuildDateLabel}</div>
- <div class="secondary">$i18n{aboutBuildDate}</div>
- </div>
+ <cr-link-row class="hr" label="$i18n{aboutBuildDetailsTitle}"
+ on-click="onBuildDetailsTap_" external>
+ </cr-link-row>
+ <div class="hr"></div>
</template>
<script src="detailed_build_info.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js
index 18ad3b217ed..ba47cf969b4 100644
--- a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js
+++ b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js
@@ -13,9 +13,6 @@ Polymer({
behaviors: [I18nBehavior],
properties: {
- /** @private {!VersionInfo} */
- versionInfo_: Object,
-
/** @private */
currentlyOnChannelText_: String,
@@ -24,17 +21,17 @@ Polymer({
/** @private */
canChangeChannel_: Boolean,
+
+ eolMessageWithMonthAndYear: {
+ type: String,
+ value: '',
+ },
},
/** @override */
ready: function() {
const browserProxy = settings.AboutPageBrowserProxyImpl.getInstance();
browserProxy.pageReady();
-
- browserProxy.getVersionInfo().then(versionInfo => {
- this.versionInfo_ = versionInfo;
- });
-
this.updateChannelInfo_();
},
@@ -51,15 +48,6 @@ Polymer({
},
/**
- * @param {string} version
- * @return {boolean}
- * @private
- */
- shouldShowVersion_: function(version) {
- return version.length > 0;
- },
-
- /**
* @param {boolean} canChangeChannel
* @return {string}
* @private
@@ -93,6 +81,15 @@ Polymer({
this.showChannelSwitcherDialog_ = true;
},
+ /**
+ * @param {!Event} e
+ * @private
+ */
+ onBuildDetailsTap_: function(e) {
+ e.preventDefault();
+ window.open('chrome://version');
+ },
+
/** @private */
onChannelSwitcherDialogClosed_: function() {
this.showChannelSwitcherDialog_ = false;
diff --git a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html
index 39116e40833..91ab92092e9 100644
--- a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html
+++ b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html
@@ -13,6 +13,11 @@
<link rel="import" href="android_apps_browser_proxy.html">
<link rel="import" href="android_apps_subpage.html">
+<!-- Changes to this file should be reflected in
+ ../chromeos/os_apps_page/os_apps_page.html.
+ TODO(crbug.com/1006152): This file should be deleted once the split-settings
+ flag has been removed. -->
+
<dom-module id="settings-android-apps-page">
<template>
<style include="settings-shared"></style>
diff --git a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html
index b0d86e21b93..92340b7c23c 100644
--- a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html
+++ b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html
@@ -18,13 +18,21 @@
<template is="dom-if" if="[[androidAppsInfo.settingsAppAvailable]]" restamp>
<cr-link-row id="manageApps" icon-class="icon-external"
label="$i18n{androidAppsManageApps}"
- on-click="onManageAndroidAppsTap_">
+ on-click="onManageAndroidAppsTap_" external>
</cr-link-row>
</template>
- <template is="dom-if" if="[[allowRemove_(prefs.arc.enabled.*)]]">
- <cr-link-row id="remove" class="hr" on-click="onRemoveTap_"
- label="$i18n{androidAppsRemove}"></cr-link-row>
+ <!-- Use 'restamp' so tests can check if the row exists. -->
+ <template is="dom-if" if="[[allowRemove_(prefs.arc.enabled.*)]]" restamp>
+ <div id="remove" class="settings-box">
+ <div id="androidRemoveLabel" class="start">
+ $i18n{androidAppsRemove}
+ </div>
+ <cr-button on-click="onRemoveTap_"
+ aria-labelledby="androidRemoveLabel">
+ $i18n{androidAppsRemoveButton}
+ </cr-button>
+ </div>
</template>
<!-- Confirm disable android apps dialog -->
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 2551cf3b191..582ae814c9e 100644
--- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -339,7 +339,7 @@ Polymer({
},
/**
- * @see content::ZoomValuesEqual().
+ * @see blink::PageZoomValuesEqual().
* @param {number} zoom1
* @param {number} zoom2
* @return {boolean}
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js
index 652a4aa59c3..ba786243f76 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js
+++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js
@@ -13,16 +13,18 @@
*/
class AutofillManager {
/**
- * Add an observer to the list of addresses.
- * @param {function(!Array<!AutofillManager.AddressEntry>):void} listener
+ * Add an observer to the list of personal data.
+ * @param {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>):void} listener
*/
- addAddressListChangedListener(listener) {}
+ setPersonalDataManagerListener(listener) {}
/**
- * Remove an observer from the list of addresses.
- * @param {function(!Array<!AutofillManager.AddressEntry>):void} listener
+ * Remove an observer from the list of personal data.
+ * @param {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>):void} listener
*/
- removeAddressListChangedListener(listener) {}
+ removePersonalDataManagerListener(listener) {}
/**
* Request the list of addresses.
@@ -49,13 +51,13 @@ AutofillManager.AddressEntry;
*/
class AutofillManagerImpl {
/** @override */
- addAddressListChangedListener(listener) {
- chrome.autofillPrivate.onAddressListChanged.addListener(listener);
+ setPersonalDataManagerListener(listener) {
+ chrome.autofillPrivate.onPersonalDataChanged.addListener(listener);
}
/** @override */
- removeAddressListChangedListener(listener) {
- chrome.autofillPrivate.onAddressListChanged.removeListener(listener);
+ removePersonalDataManagerListener(listener) {
+ chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener);
}
/** @override */
@@ -117,21 +119,30 @@ Polymer({
autofillManager_: null,
/**
- * @type {?function(!Array<!AutofillManager.AddressEntry>)}
+ * @type {?function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>)}
* @private
*/
- setAddressesListener_: null,
+ setPersonalDataListener_: null,
/** @override */
attached: function() {
// Create listener functions.
/** @type {function(!Array<!AutofillManager.AddressEntry>)} */
- const setAddressesListener = list => {
- this.addresses = list;
+ const setAddressesListener = addressList => {
+ this.addresses = addressList;
+ };
+
+ /**
+ * @type {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>)}
+ */
+ const setPersonalDataListener = (addressList, cardList) => {
+ this.addresses = addressList;
};
// Remember the bound reference in order to detach.
- this.setAddressesListener_ = setAddressesListener;
+ this.setPersonalDataListener_ = setPersonalDataListener;
// Set the managers. These can be overridden by tests.
this.autofillManager_ = AutofillManagerImpl.getInstance();
@@ -140,7 +151,8 @@ Polymer({
this.autofillManager_.getAddressList(setAddressesListener);
// Listen for changes.
- this.autofillManager_.addAddressListChangedListener(setAddressesListener);
+ this.autofillManager_.setPersonalDataManagerListener(
+ setPersonalDataListener);
// Record that the user opened the address settings.
chrome.metricsPrivate.recordUserAction('AutofillAddressesViewed');
@@ -148,9 +160,12 @@ Polymer({
/** @override */
detached: function() {
- this.autofillManager_.removeAddressListChangedListener(
- /** @type {function(!Array<!AutofillManager.AddressEntry>)} */ (
- this.setAddressesListener_));
+ this.autofillManager_.removePersonalDataManagerListener(
+ /**
+ @type {function(!Array<!AutofillManager.AddressEntry>,
+ !Array<!PaymentsManager.CreditCardEntry>)}
+ */
+ (this.setPersonalDataListener_));
},
/**
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html
index 847f192031d..922166b2951 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html
+++ b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html
@@ -50,8 +50,7 @@
}
</style>
<div class="list-item" focus-row-container>
- <div class="website-column no-min-width"
- title="[[item.entry.urls.link]]">
+ <div class="website-column no-min-width">
<site-favicon url="[[item.entry.urls.link]]"></site-favicon>
<a id="originUrl" target="_blank" class="no-min-width"
href="[[item.entry.urls.link]]"
@@ -64,14 +63,17 @@
</a>
</div>
<input id="username" class="username-column password-field"
- readonly tabindex="-1" value="[[item.entry.username]]">
+ aria-label="$i18n{editPasswordUsernameLabel}"
+ readonly value="[[item.entry.username]]"
+ focus-row-control focus-type="username">
<div class="password-column">
<template is="dom-if" if="[[!item.entry.federationText]]">
<input id="password" aria-label=$i18n{editPasswordPasswordLabel}
type="[[getPasswordInputType_(item.password)]]"
on-click="onReadonlyInputTap_" class="password-field" readonly
disabled$="[[!item.password]]"
- value="[[getPassword_(item.password)]]">
+ value="[[getPassword_(item.password)]]"
+ focus-row-control focus-type="passwordField">
<cr-icon-button id="showPasswordButton"
class$="[[getIconClass_(item.password)]]"
on-click="onShowPasswordButtonTap_"
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 58e376e7433..2f569d3e4dc 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html
+++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -10,12 +10,14 @@
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/list_property_update_behavior.html">
<link rel="import" href="chrome://resources/html/util.html">
+<link rel="import" href="chrome://resources/html/web_ui_listener_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-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
-<link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../controls/extension_controlled_indicator.html">
+<link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../global_scroll_target_behavior.html">
+<link rel="import" href="../people_page/sync_browser_proxy.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../settings_shared_css.html">
@@ -73,16 +75,6 @@
</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}"
@@ -108,7 +100,8 @@
</div>
<div class="list-frame">
<div id="savedPasswordsHeaders" class="list-item column-header"
- hidden$="[[!hasSome_(savedPasswords, savedPasswords.splices)]]">
+ hidden$="[[!hasSome_(savedPasswords, savedPasswords.splices)]]"
+ aria-hidden="true">
<div class="website-column">$i18n{editPasswordWebsiteLabel}</div>
<div class="username-column">
$i18n{editPasswordUsernameLabel}
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 a98d69646d4..0eabb41138a 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js
+++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -102,12 +102,6 @@ Polymer({
},
/** @private */
- passwordsLeakDetectionEnabled_: {
- type: Boolean,
- value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'),
- },
-
- /** @private */
showExportPasswords_: {
type: Boolean,
computed: 'hasPasswords_(savedPasswords.splices)',
@@ -125,23 +119,12 @@ 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,
@@ -266,13 +249,6 @@ Polymer({
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);
@@ -363,24 +339,6 @@ Polymer({
},
/**
- * @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
@@ -396,20 +354,6 @@ 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
@@ -426,7 +370,9 @@ Polymer({
onMenuRemovePasswordTap_: function() {
this.passwordManager_.removeSavedPassword(
this.activePassword.item.entry.id);
- cr.toastManager.getInstance().show(this.i18n('passwordDeleted'), false);
+ cr.toastManager.getInstance().show(
+ this.i18n('passwordDeleted'),
+ /* showUndo */ true);
/** @type {CrActionMenuElement} */ (this.$.menu).close();
},
@@ -544,6 +490,6 @@ Polymer({
showImportOrExportPasswords_: function(
showExportPasswords, showImportPasswords) {
return showExportPasswords || showImportPasswords;
- }
+ },
});
})();
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html
index 5836b23e617..2109d3395fd 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html
+++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html
@@ -42,6 +42,20 @@
pref="{{prefs.autofill.credit_card_enabled}}">
</settings-toggle-button>
<template is="dom-if"
+ if="[[shouldShowFidoToggle_(
+ prefs.autofill.credit_card_enabled.value,
+ userIsFidoVerifiable_)]]">
+ <settings-toggle-button
+ class="settings-box first"
+ id="autofillCreditCardFIDOAuthToggle"
+ aria-label="$i18n{creditCards}" no-extension-indicator
+ label="$i18n{enableCreditCardFIDOAuthLabel}"
+ sub-label="$i18n{enableCreditCardFIDOAuthSublabel}"
+ pref="{{prefs.autofill.credit_card_fido_auth_enabled}}"
+ on-change="setFIDOAuthenticationEnabledState_">
+ </settings-toggle-button>
+ </template>
+ <template is="dom-if"
if="[[prefs.autofill.credit_card_enabled.extensionId]]">
<div class="settings-box continuation">
<extension-controlled-indicator class="start"
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js
index 03d51d23ebf..0c71a4b46c6 100644
--- a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js
+++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js
@@ -13,16 +13,18 @@
*/
class PaymentsManager {
/**
- * Add an observer to the list of credit cards.
- * @param {function(!Array<!PaymentsManager.CreditCardEntry>):void} listener
+ * Add an observer to the list of personal data.
+ * @param {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>):void} listener
*/
- addCreditCardListChangedListener(listener) {}
+ setPersonalDataManagerListener(listener) {}
/**
- * Remove an observer from the list of credit cards.
- * @param {function(!Array<!PaymentsManager.CreditCardEntry>):void} listener
+ * Remove an observer from the list of personal data.
+ * @param {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>):void} listener
*/
- removeCreditCardListChangedListener(listener) {}
+ removePersonalDataManagerListener(listener) {}
/**
* Request the list of credit cards.
@@ -51,6 +53,11 @@ class PaymentsManager {
* Logs that the server cards edit link was clicked.
*/
logServerCardLinkClicked() {}
+
+ /**
+ * Enables FIDO authentication for card unmasking.
+ */
+ setCreditCardFIDOAuthEnabledState(enabled) {}
}
/** @typedef {chrome.autofillPrivate.CreditCardEntry} */
@@ -62,13 +69,13 @@ PaymentsManager.CreditCardEntry;
*/
class PaymentsManagerImpl {
/** @override */
- addCreditCardListChangedListener(listener) {
- chrome.autofillPrivate.onCreditCardListChanged.addListener(listener);
+ setPersonalDataManagerListener(listener) {
+ chrome.autofillPrivate.onPersonalDataChanged.addListener(listener);
}
/** @override */
- removeCreditCardListChangedListener(listener) {
- chrome.autofillPrivate.onCreditCardListChanged.removeListener(listener);
+ removePersonalDataManagerListener(listener) {
+ chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener);
}
/** @override */
@@ -100,6 +107,11 @@ class PaymentsManagerImpl {
logServerCardLinkClicked() {
chrome.autofillPrivate.logServerCardLinkClicked();
}
+
+ /** @override */
+ setCreditCardFIDOAuthEnabledState(enabled) {
+ chrome.autofillPrivate.setCreditCardFIDOAuthEnabledState(enabled);
+ }
}
cr.addSingletonGetter(PaymentsManagerImpl);
@@ -126,6 +138,18 @@ Polymer({
},
/**
+ * Set to true if user can be verified through FIDO authentication.
+ * @private
+ */
+ userIsFidoVerifiable_: {
+ type: Boolean,
+ value: function() {
+ return loadTimeData.getBoolean(
+ 'fidoAuthenticationAvailableForAutofill');
+ },
+ },
+
+ /**
* The model for any credit card related action menus or dialogs.
* @private {?chrome.autofillPrivate.CreditCardEntry}
*/
@@ -170,21 +194,39 @@ Polymer({
PaymentsManager_: null,
/**
- * @type {?function(!Array<!PaymentsManager.CreditCardEntry>)}
+ * @type {?function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>)}
* @private
*/
- setCreditCardsListener_: null,
+ setPersonalDataListener_: null,
/** @override */
attached: function() {
// Create listener function.
/** @type {function(!Array<!PaymentsManager.CreditCardEntry>)} */
- const setCreditCardsListener = list => {
- this.creditCards = list;
+ const setCreditCardsListener = cardList => {
+ this.creditCards = cardList;
+ };
+
+ // Update |userIsFidoVerifiable_| based on the availability of a platform
+ // authenticator.
+ if (window.PublicKeyCredential) {
+ window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
+ .then(r => {
+ this.userIsFidoVerifiable_ = this.userIsFidoVerifiable_ && r;
+ });
+ }
+
+ /**
+ * @type {function(!Array<!AutofillManager.AddressEntry>,
+ * !Array<!PaymentsManager.CreditCardEntry>)}
+ */
+ const setPersonalDataListener = (addressList, cardList) => {
+ this.creditCards = cardList;
};
// Remember the bound reference in order to detach.
- this.setCreditCardsListener_ = setCreditCardsListener;
+ this.setPersonalDataListener_ = setPersonalDataListener;
// Set the managers. These can be overridden by tests.
this.paymentsManager_ = PaymentsManagerImpl.getInstance();
@@ -193,8 +235,8 @@ Polymer({
this.paymentsManager_.getCreditCardList(setCreditCardsListener);
// Listen for changes.
- this.paymentsManager_.addCreditCardListChangedListener(
- setCreditCardsListener);
+ this.paymentsManager_.setPersonalDataManagerListener(
+ setPersonalDataListener);
// Record that the user opened the payments settings.
chrome.metricsPrivate.recordUserAction('AutofillCreditCardsViewed');
@@ -202,9 +244,12 @@ Polymer({
/** @override */
detached: function() {
- this.paymentsManager_.removeCreditCardListChangedListener(
- /** @type {function(!Array<!PaymentsManager.CreditCardEntry>)} */ (
- this.setCreditCardsListener_));
+ this.paymentsManager_.removePersonalDataManagerListener(
+ /**
+ @type {function(!Array<!AutofillManager.AddressEntry>,
+ !Array<!PaymentsManager.CreditCardEntry>)}
+ */
+ (this.setPersonalDataListener_));
},
/**
@@ -311,6 +356,25 @@ Polymer({
},
/**
+ * @param {boolean} creditCardEnabled
+ * @return {boolean} Whether or not the user is verifiable through FIDO
+ * authentication.
+ * @private
+ */
+ shouldShowFidoToggle_: function(creditCardEnabled, userIsFidoVerifiable) {
+ return creditCardEnabled && userIsFidoVerifiable;
+ },
+
+ /**
+ * Listens for the enable-authentication event, and calls the private API.
+ * @private
+ */
+ setFIDOAuthenticationEnabledState_: function() {
+ this.paymentsManager_.setCreditCardFIDOAuthEnabledState(
+ this.$$('#autofillCreditCardFIDOAuthToggle').checked);
+ },
+
+ /**
* @param {!Array<!PaymentsManager.CreditCardEntry>} creditCards
* @param {boolean} creditCardEnabled
* @return {boolean} Whether to show the migration button.
diff --git a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
index ab89a35dd33..5cbc3c1c317 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -23,5 +23,5 @@ js_library("basic_page") {
"//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
- externs_list = [ "$externs_path/pending.js" ]
+ externs_list = [ "$externs_path/pending_polymer.js" ]
}
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 46deb873d7d..7c40d63c9d1 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -119,8 +119,7 @@
$i18nRaw{osSettingsBannerText}
</div>
<cr-icon-button class="icon-clear"
- id="hideOSSettings"
- aria-label="$i18n{clear}"
+ title="$i18n{close}"
on-click="onOSSettingsBannerClosed_">
</cr-icon-button>
</div>
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 f2f0131a77c..f12eb098ddc 100644
--- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -153,11 +153,6 @@ Polymer({
this.showChangePassword = visibility;
});
- if (loadTimeData.getBoolean('passwordProtectionAvailable')) {
- settings.ChangePasswordBrowserProxyImpl.getInstance()
- .initializeChangePasswordHandler();
- }
-
if (settings.AndroidAppsBrowserProxyImpl) {
this.addWebUIListener(
'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this));
diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
index b883f4e20f1..75b6aea70fc 100644
--- a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
@@ -7,10 +7,12 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":os_a11y_page",
+ "../../a11y_page:captions_subpage",
"../../a11y_page:externs",
"../../a11y_page:manage_a11y_page",
"../../a11y_page:switch_access_subpage",
"../../a11y_page:tts_subpage",
+ "../../appearance_page:fonts_browser_proxy",
]
}
diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
index b54af0ac04f..664cc90da69 100644
--- a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn
@@ -13,8 +13,13 @@ js_type_check("closure_compile") {
js_library("os_apps_page") {
deps = [
"../../:route",
+ "../../android_apps_page:android_apps_browser_proxy",
+ "../../android_apps_page:android_apps_subpage",
+ "../../prefs:prefs_behavior",
"../../settings_page:settings_animated_pages",
"app_management_page",
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:i18n_behavior",
]
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
index c9841d1a9d7..b0e0b80ace2 100644
--- 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
@@ -19,11 +19,9 @@ js_type_check("closure_compile") {
":fake_page_handler",
":main_view",
":permission_item",
- ":permission_toggle",
":pin_to_shelf_item",
":pwa_permission_view",
":reducers",
- ":router",
":store",
":store_client",
":toggle_row",
@@ -62,7 +60,6 @@ js_library("app_management_page") {
":actions",
":browser_proxy",
":main_view",
- ":router",
":store",
":store_client",
]
@@ -75,6 +72,7 @@ js_library("app_permission_view") {
":dom_switch",
":pwa_permission_view",
":store_client",
+ "../../..:route",
]
}
@@ -133,14 +131,8 @@ js_library("main_view") {
js_library("permission_item") {
deps = [
":fake_page_handler",
- ":permission_toggle",
":store_client",
- ":util",
- ]
-}
-
-js_library("permission_toggle") {
- deps = [
+ ":toggle_row",
":util",
]
}
@@ -171,14 +163,6 @@ js_library("reducers") {
]
}
-js_library("router") {
- deps = [
- ":actions",
- ":constants",
- ":store_client",
- ]
-}
-
js_library("store") {
deps = [
":reducers",
@@ -218,6 +202,7 @@ js_library("uninstall_button") {
":util",
"//ui/webui/resources/cr_elements/cr_button:cr_button",
"//ui/webui/resources/cr_elements/policy:cr_tooltip_icon",
+ "//ui/webui/resources/js:i18n_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 058863d4b69..6aa19594fe9 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
@@ -18,7 +18,7 @@ js_library("os_settings_ui") {
"../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/chromeos/network:cr_onc_strings",
"//ui/webui/resources/cr_elements/cr_drawer:cr_drawer",
"//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field",
"//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior",
diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.html b/chromium/chrome/browser/resources/settings/controls/controlled_button.html
index af328098f62..79fb7d2e405 100644
--- a/chromium/chrome/browser/resources/settings/controls/controlled_button.html
+++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.html
@@ -42,7 +42,7 @@
}
</style>
- <cr-button class$="[[getClass_(actionButton)]]"
+ <cr-button class$="[[actionClass_]]"
disabled="[[!buttonEnabled_(enforced_, disabled)]]">
[[label]]
</cr-button>
diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.js b/chromium/chrome/browser/resources/settings/controls/controlled_button.js
index 43f07fd36c0..e751237cab2 100644
--- a/chromium/chrome/browser/resources/settings/controls/controlled_button.js
+++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.js
@@ -11,11 +11,6 @@ Polymer({
],
properties: {
- actionButton: {
- type: Boolean,
- value: false,
- },
-
endJustified: {
type: Boolean,
value: false,
@@ -31,6 +26,12 @@ Polymer({
},
/** @private */
+ actionClass_: {
+ type: String,
+ value: ''
+ },
+
+ /** @private */
enforced_: {
type: Boolean,
computed: 'isPrefEnforced(pref.*)',
@@ -38,6 +39,18 @@ Polymer({
},
},
+ /** @override */
+ attached: function() {
+ if (this.classList.contains('action-button')) {
+ this.actionClass_ = 'action-button';
+ }
+ },
+
+ /** Focus on the inner cr-button. */
+ focus: function() {
+ this.$$('cr-button').focus();
+ },
+
/**
* @param {!Event} e
* @private
@@ -49,15 +62,6 @@ Polymer({
},
/**
- * @param {!boolean} actionButton
- * @return {string} Class of the cr-button.
- * @private
- */
- getClass_: function(actionButton) {
- return actionButton ? 'action-button' : '';
- },
-
- /**
* @param {!boolean} enforced
* @param {!boolean} disabled
* @return {boolean} True if the button should be enabled.
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 4a0026ee454..810fd0b8b00 100644
--- a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html
+++ b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html
@@ -13,13 +13,16 @@
}
#passwordPrompt {
- padding: 0;
+ padding-bottom: 20px;
+ padding-inline-end: 0;
+ padding-inline-start: 0;
}
</style>
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">$i18n{passwordPromptTitle}</div>
<div slot="body">
- <div id="passwordPrompt" class="settings-box first line-only">
+ <div id="passwordPrompt" class="settings-box first"
+ hidden="[[!passwordPromptText]]">
[[passwordPromptText]]
</div>
<cr-input id="passwordInput" type="password"
diff --git a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js
index 2fc160bfb77..574dd209c16 100644
--- a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js
+++ b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js
@@ -34,6 +34,7 @@ Polymer({
passwordPromptText: {
type: String,
notify: true,
+ value: '',
},
/**
diff --git a/chromium/chrome/browser/resources/settings/device_page/BUILD.gn b/chromium/chrome/browser/resources/settings/device_page/BUILD.gn
index d7d0c1e13fd..1826cc4de8d 100644
--- a/chromium/chrome/browser/resources/settings/device_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/device_page/BUILD.gn
@@ -12,7 +12,6 @@ js_type_check("closure_compile") {
":display_layout",
":display_overscan_dialog",
":drag_behavior",
- ":drive_cache_dialog",
":keyboard",
":layout_behavior",
":night_light_slider",
@@ -148,10 +147,3 @@ js_library("storage") {
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
}
-
-js_library("drive_cache_dialog") {
- deps = [
- "//ui/webui/resources/js:i18n_behavior",
- ]
- externs_list = [ "$externs_path/chrome_send.js" ]
-}
diff --git a/chromium/chrome/browser/resources/settings/device_page/display.html b/chromium/chrome/browser/resources/settings/device_page/display.html
index 5b906f084eb..cee6fafa793 100644
--- a/chromium/chrome/browser/resources/settings/device_page/display.html
+++ b/chromium/chrome/browser/resources/settings/device_page/display.html
@@ -241,12 +241,13 @@
pref="{{prefs.ash.night_light.enabled}}"
sub-label="$i18n{displayNightLightText}">
</settings-toggle-button>
+
<div id="nightLightSettingsDiv"
class="settings-box continuation start layout vertical">
<!-- Color temperature slider -->
<div id="nightLightTemperatureDiv"
class="settings-box indented continuation"
- disabled$="[[!prefs.ash.night_light.enabled.value]]">
+ hidden$="[[!prefs.ash.night_light.enabled.value]]">
<div class="start text-area" id="colorTemperatureLabel">
$i18n{displayNightLightTemperatureLabel}
</div>
@@ -254,8 +255,7 @@
aria-labelledby="colorTemperatureLabel" min="0" max="100"
scale="100" label-min="$i18n{displayNightLightTempSliderMinLabel}"
label-max="$i18n{displayNightLightTempSliderMaxLabel}"
- pref="{{prefs.ash.night_light.color_temperature}}"
- disabled$="[[!prefs.ash.night_light.enabled.value]]">
+ pref="{{prefs.ash.night_light.color_temperature}}">
</settings-slider>
</div>
<!-- Schedule settings -->
@@ -278,7 +278,7 @@
</div>
<!-- Custom schedule slider -->
<iron-collapse id="nightLightCustomScheduleCollapse"
- opened="[[shouldOpenCustomScheduleCollapse_]]">
+ opened="[[shouldOpenCustomScheduleCollapse_]]">
<div class="settings-box indented continuation">
<div class="start text-area layout vertical">
<div class="settings-box continuation self-stretch">
diff --git a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html b/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html
deleted file mode 100644
index 00e43a44464..00000000000
--- a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<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_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="../settings_shared_css.html">
-
-<dom-module id="settings-drive-cache-dialog">
- <template>
- <style include="settings-shared"></style>
- <cr-dialog id="dialog" close-text="$i18n{close}">
- <div slot="title">
- $i18n{storageClearDriveCacheDialogTitle}
- </div>
- <div slot="body">
- <span>$i18n{storageClearDriveCacheDialogDescription}</span>
- </div>
- <div slot="button-container">
- <cr-button id="cancelButton" class="cancel-button"
- on-click="onCancelTap_">
- $i18n{cancel}
- </cr-button>
- <cr-button id="deleteButton" class="action-button"
- on-click="onDeleteTap_">
- $i18n{storageDeleteAllButtonTitle}
- </cr-button>
- </div>
- </cr-dialog>
- </template>
- <script src="drive_cache_dialog.js"></script>
-</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js b/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js
deleted file mode 100644
index fd63087ec6a..00000000000
--- a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js
+++ /dev/null
@@ -1,31 +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.
-
-/**
- * @fileoverview
- * 'settings-drive-cache-dialog' is the dialog to delete Google Drive temporary
- * offline files.
- */
-Polymer({
- is: 'settings-drive-cache-dialog',
-
- behaviors: [
- I18nBehavior,
- ],
-
- open: function() {
- this.$.dialog.showModal();
- },
-
- /** @private */
- onCancelTap_: function() {
- this.$.dialog.cancel();
- },
-
- /** @private */
- onDeleteTap_: function() {
- chrome.send('clearDriveCache');
- this.$.dialog.close();
- },
-});
diff --git a/chromium/chrome/browser/resources/settings/device_page/keyboard.js b/chromium/chrome/browser/resources/settings/device_page/keyboard.js
index 4c189aa6727..a636592e369 100644
--- a/chromium/chrome/browser/resources/settings/device_page/keyboard.js
+++ b/chromium/chrome/browser/resources/settings/device_page/keyboard.js
@@ -155,7 +155,7 @@ Polymer({
onShowLanguageInputTap_: function() {
settings.navigateTo(
- settings.routes.LANGUAGES,
+ settings.routes.LANGUAGES_DETAILS,
/* dynamicParams */ null, /* removeSearch */ true);
},
diff --git a/chromium/chrome/browser/resources/settings/device_page/pointers.html b/chromium/chrome/browser/resources/settings/device_page/pointers.html
index fff070da29c..6a628f2f5b2 100644
--- a/chromium/chrome/browser/resources/settings/device_page/pointers.html
+++ b/chromium/chrome/browser/resources/settings/device_page/pointers.html
@@ -46,7 +46,7 @@
<template is="dom-if" if="[[allowDisableAcceleration_]]">
<settings-toggle-button id="mouseAcceleration"
pref="{{prefs.settings.mouse.acceleration}}"
- label="$i18n{pointerAccelerationLabel}">
+ label="$i18n{mouseAccelerationLabel}">
</settings-toggle-button>
</template>
<div class="settings-box">
@@ -75,7 +75,7 @@
<template is="dom-if" if="[[allowDisableAcceleration_]]">
<settings-toggle-button id="touchpadAcceleration"
pref="{{prefs.settings.touchpad.acceleration}}"
- label="$i18n{pointerAccelerationLabel}">
+ label="$i18n{touchpadAccelerationLabel}">
</settings-toggle-button>
</template>
<div class="settings-box">
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.html b/chromium/chrome/browser/resources/settings/device_page/storage.html
index f0a518e2572..6526d4f1fb1 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage.html
+++ b/chromium/chrome/browser/resources/settings/device_page/storage.html
@@ -8,7 +8,6 @@
<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.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="drive_cache_dialog.html">
<link rel="import" href="storage_external.html">
<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../route.html">
@@ -201,20 +200,6 @@
<cr-link-row id="downloadsSize" class="hr" on-click="onDownloadsTap_"
label="$i18n{storageItemDownloads}"
sub-label="$i18n{storageSizeComputing}" external></cr-link-row>
- <template is="dom-if" if="[[driveEnabled_]]">
- <div class="settings-box two-line" on-click="onDriveCacheTap_"
- actionable$="[[hasDriveCache_]]" >
- <div class="start">
- $i18n{storageItemDriveCache}
- <div id="driveCacheSize" class="secondary">
- $i18n{storageSizeComputing}
- </div>
- </div>
- <cr-icon-button class="icon-delete-gray" id="deleteButton"
- aria-label="$i18n{storageItemDriveCache}"
- aria-describedby="driveSizeCache"></cr-icon-button>
- </div>
- </template>
<cr-link-row id="browsingDataSize" class="hr" on-click="onBrowsingDataTap_"
label="$i18n{storageItemBrowsingData}"
sub-label="$i18n{storageSizeComputing}" external></cr-link-row>
@@ -238,10 +223,6 @@
on-click="onExternalStoragePreferencesTap_"
label="$i18n{storageExternal}"></cr-link-row>
</template>
-
- <settings-drive-cache-dialog id="storageDriveCache"
- on-close="onCloseDriveCacheDialog_">
- </settings-drive-cache-dialog>
</template>
<script src="storage.js"></script>
</dom-module>
diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.js b/chromium/chrome/browser/resources/settings/device_page/storage.js
index 2717462da66..ae7598fdbba 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage.js
+++ b/chromium/chrome/browser/resources/settings/device_page/storage.js
@@ -37,12 +37,6 @@ Polymer({
behaviors: [settings.RouteObserverBehavior, WebUIListenerBehavior],
properties: {
- /** @private */
- driveEnabled_: {
- type: Boolean,
- value: false,
- },
-
androidEnabled: Boolean,
/** @private */
@@ -68,12 +62,6 @@ Polymer({
}
},
- /** @private */
- hasDriveCache_: {
- type: Boolean,
- value: false,
- },
-
/** @private {settings.StorageSizeStat} */
sizeStat_: Object,
},
@@ -94,9 +82,6 @@ Polymer({
'storage-downloads-size-changed',
this.handleDownloadsSizeChanged_.bind(this));
this.addWebUIListener(
- 'storage-drive-cache-size-changed',
- this.handleDriveCacheSizeChanged_.bind(this));
- this.addWebUIListener(
'storage-browsing-data-size-changed',
this.handleBrowsingDataSizeChanged_.bind(this));
this.addWebUIListener(
@@ -111,9 +96,6 @@ Polymer({
this.handleOtherUsersSizeChanged_.bind(this));
}
this.addWebUIListener(
- 'storage-drive-enabled-changed',
- this.handleDriveEnabledChanged_.bind(this));
- this.addWebUIListener(
'storage-android-running-changed',
this.handleAndroidRunningChanged_.bind(this));
},
@@ -146,18 +128,6 @@ Polymer({
},
/**
- * Handler for tapping the "Offline files" item.
- * @param {!Event} e
- * @private
- */
- onDriveCacheTap_: function(e) {
- e.preventDefault();
- if (this.hasDriveCache_) {
- this.$.storageDriveCache.open();
- }
- },
-
- /**
* Handler for tapping the "Browsing data" item.
* @private
*/
@@ -221,19 +191,6 @@ Polymer({
},
/**
- * @param {string} size Formatted string representing the size of Offline
- * files.
- * @param {boolean} hasCache True if the device has at least one offline file.
- * @private
- */
- handleDriveCacheSizeChanged_: function(size, hasCache) {
- if (this.driveEnabled_) {
- this.$$('#driveCacheSize').textContent = size;
- this.hasDriveCache_ = hasCache;
- }
- },
-
- /**
* @param {string} size Formatted string representing the size of Browsing
* data.
* @private
@@ -275,14 +232,6 @@ Polymer({
},
/**
- * @param {boolean} enabled True if Google Drive is enabled.
- * @private
- */
- handleDriveEnabledChanged_: function(enabled) {
- this.driveEnabled_ = enabled;
- },
-
- /**
* @param {boolean} running True if Android (ARC) is running.
* @private
*/
@@ -362,9 +311,4 @@ Polymer({
return '';
}
},
-
- /** @private */
- onCloseDriveCacheDialog_: function() {
- cr.ui.focusWithoutInk(assert(this.$$('#deleteButton')));
- },
});
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 922c2613d1f..da2d3cafc7d 100644
--- a/chromium/chrome/browser/resources/settings/device_page/storage_external.html
+++ b/chromium/chrome/browser/resources/settings/device_page/storage_external.html
@@ -15,7 +15,7 @@
</style>
<div class="settings-box first">
<span>
- $i18n{storageAndroidAppsExternalDrivesNote}
+ $i18nRaw{storageAndroidAppsExternalDrivesNote}
</span>
</div>
<h2>$i18n{storageExternalStorageListHeader}</h2>
diff --git a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
index 131565b3c41..52053aae4d7 100644
--- a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
+++ b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
@@ -58,12 +58,9 @@
<div class="label">
$i18n{googleAssistantEnableHotword}
</div>
- <div class="secondary label" hidden="[[!hotwordDefaultOn_]]">
+ <div class="secondary label">
$i18n{googleAssistantEnableHotwordWithoutDspDescription}
</div>
- <div class="secondary label" hidden="[[hotwordDefaultOn_]]">
- $i18n{googleAssistantEnableHotwordDescription}
- </div>
</div>
<template is="dom-if" if="[[hotwordEnforced_]]" restamp>
<cr-policy-pref-indicator id="hotword-policy-pref-indicator"
@@ -87,7 +84,7 @@
</select>
</div>
<template is="dom-if" if="[[shouldShowVoiceMatchSettings_]]">
- <div class="settings-box">
+ <div class="settings-box continuation embedded">
<div class="start text-area settings-box-text">
<div class="label">
$i18n{googleAssistantVoiceSettings}
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 559d65184d1..5237e0168f7 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
@@ -15,8 +15,8 @@ const DspHotwordState = {
/**
* Indicates user's activity control consent status.
*
- * Note: This should be kept in sync with ash::mojom::ConsentStatus in
- * ash/public/mojom/voice_interaction_controller.mojom
+ * Note: This should be kept in sync with ConsentStatus in
+ * chromeos/services/assistant/public/cpp/assistant_prefs.h
* @enum {number}
*/
const ConsentStatus = {
@@ -97,12 +97,6 @@ Polymer({
},
/** @private */
- hotwordDefaultOn_: {
- type: Boolean,
- value: false,
- },
-
- /** @private */
dspHotwordState_: {
type: DspHotwordState,
}
@@ -166,20 +160,17 @@ Polymer({
this.setPrefValue('settings.voice_interaction.hotword.enabled', true);
this.setPrefValue(
'settings.voice_interaction.hotword.always_on', false);
- this.hotwordDefaultOn_ = true;
this.browserProxy_.syncVoiceModelStatus();
break;
case DspHotwordState.ALWAYS_ON:
this.setPrefValue('settings.voice_interaction.hotword.enabled', true);
this.setPrefValue('settings.voice_interaction.hotword.always_on', true);
- this.hotwordDefaultOn_ = false;
this.browserProxy_.syncVoiceModelStatus();
break;
case DspHotwordState.OFF:
this.setPrefValue('settings.voice_interaction.hotword.enabled', false);
this.setPrefValue(
'settings.voice_interaction.hotword.always_on', false);
- this.hotwordDefaultOn_ = false;
break;
default:
console.error('Invalid Dsp hotword settings state');
@@ -205,6 +196,7 @@ Polymer({
this.refreshDspHotwordState_();
this.shouldShowVoiceMatchSettings_ =
+ !loadTimeData.getBoolean('voiceMatchDisabled') &&
this.getPref('settings.voice_interaction.hotword.enabled.value') &&
(this.getPref(
'settings.voice_interaction.activity_control.consent_status.value') ==
@@ -220,14 +212,11 @@ Polymer({
/** @private */
refreshDspHotwordState_: function() {
if (!this.getPref('settings.voice_interaction.hotword.enabled.value')) {
- this.hotwordDefaultOn_ = false;
this.dspHotwordState_ = DspHotwordState.OFF;
} else if (this.getPref(
'settings.voice_interaction.hotword.always_on.value')) {
- this.hotwordDefaultOn_ = false;
this.dspHotwordState_ = DspHotwordState.ALWAYS_ON;
} else {
- this.hotwordDefaultOn_ = true;
this.dspHotwordState_ = DspHotwordState.DEFAULT_ON;
}
diff --git a/chromium/chrome/browser/resources/settings/icons.html b/chromium/chrome/browser/resources/settings/icons.html
index ad722128231..595f018d907 100644
--- a/chromium/chrome/browser/resources/settings/icons.html
+++ b/chromium/chrome/browser/resources/settings/icons.html
@@ -74,6 +74,7 @@ NOTE: Chrome OS icons go in ./chromeos/os_icons.html.
<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>
<g id="payment-handler"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"></path></g>
+ <g id="insecure-content"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
<g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"></path></g>
<g id="power-settings-new"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"></path></g>
<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>
diff --git a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
index 7b8a8fa0718..5aa49429248 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn
@@ -28,7 +28,6 @@ js_library("internet_page") {
"//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",
"//ui/webui/resources/js:web_ui_listener_behavior",
@@ -51,7 +50,6 @@ js_library("internet_config") {
deps = [
"..:route",
"//ui/webui/resources/cr_components/chromeos/network:network_config",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
"//ui/webui/resources/cr_elements/cr_dialog:cr_dialog",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
@@ -67,7 +65,6 @@ js_library("internet_detail_page") {
":tether_connection_dialog",
"..: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_mojo",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
@@ -82,7 +79,6 @@ js_library("internet_detail_page") {
js_library("internet_known_networks_page") {
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/cr_action_menu:cr_action_menu",
"//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo",
"//ui/webui/resources/js:assert",
@@ -122,7 +118,6 @@ js_library("network_proxy_section") {
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/js:assert",
"//ui/webui/resources/js/chromeos:onc_mojo",
]
@@ -131,7 +126,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/chromeos/network:cr_onc_strings",
"//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_config.html b/chromium/chrome/browser/resources/settings/internet_page/internet_config.html
index df873613ea5..65ef26edeee 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.html
@@ -1,7 +1,6 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_config.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/html/i18n_behavior.html">
@@ -23,13 +22,11 @@
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">
- [[getDialogTitle_(managedProperties_, showConnect)]]
+ [[getDialogTitle_(name, type, showConnect)]]
</div>
<div slot="body">
<network-config id="networkConfig" class="flex"
- networking-private="[[networkingPrivate]]"
- global-policy="[[globalPolicy]]"
- managed-properties="{{managedProperties_}}"
+ guid="[[guid]]" name="{{name}}" type="{{type}}"
enable-connect="{{enableConnect_}}" enable-save="{{enableSave_}}"
share-allow-enable="[[shareAllowEnable_]]"
share-default="[[shareDefault_]]"
diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_config.js b/chromium/chrome/browser/resources/settings/internet_page/internet_config.js
index 0b3760d0477..d5bd42d5da2 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.js
@@ -12,15 +12,6 @@ Polymer({
behaviors: [I18nBehavior],
properties: {
- /**
- * Interface for networkingPrivate calls, passed from internet_page.
- * @type {NetworkingPrivate}
- */
- networkingPrivate: Object,
-
- /** @type {!chrome.networkingPrivate.GlobalPolicy|undefined} */
- globalPolicy: Object,
-
/** @private */
shareAllowEnable_: {
type: Boolean,
@@ -44,13 +35,14 @@ Polymer({
guid: String,
/**
- * The type of network to be configured.
- * @type {!chrome.networkingPrivate.NetworkType}
+ * The type of network to be configured as a string. May be set initially or
+ * updated by network-config.
*/
type: String,
/**
- * The name of network (for display while the network details are fetched).
+ * The name of the network. May be set initially or updated by
+ * network-config.
*/
name: String,
@@ -66,14 +58,6 @@ Polymer({
enableSave_: Boolean,
/**
- * The current properties if an existing network is being configured, or
- * a minimal subset for a new network. Note: network-config may modify
- * this (specifically .name).
- * @private {!chrome.networkingPrivate.ManagedProperties}
- */
- managedProperties_: Object,
-
- /**
* Set by network-config when a configuration error occurs.
* @private
*/
@@ -89,14 +73,6 @@ Polymer({
dialog.showModal();
}
- // Set managedProperties for new configurations and for existing
- // configurations until the current properties are loaded.
- assert(this.type && this.type != CrOnc.Type.ALL);
- this.managedProperties_ = {
- GUID: this.guid,
- Name: {Active: this.name},
- Type: this.type,
- };
this.$.networkConfig.init();
},
@@ -113,7 +89,6 @@ Polymer({
*/
onClose_: function(event) {
this.close();
- event.stopPropagation();
},
/**
@@ -121,18 +96,10 @@ Polymer({
* @private
*/
getDialogTitle_: function() {
- // If no properties are available yet, wait until they are set as part of
- // open().
- if (!this.managedProperties_) {
- return '';
- }
-
- const name = /** @type {string} */ (
- CrOnc.getActiveValue(this.managedProperties_.Name));
- if (name && !this.showConnect) {
- return this.i18n('internetConfigName', HTMLEscape(name));
+ if (this.name && !this.showConnect) {
+ return this.i18n('internetConfigName', HTMLEscape(this.name));
}
- const type = this.i18n('OncType' + this.managedProperties_.Type);
+ const type = this.i18n('OncType' + this.type);
return this.i18n('internetJoinType', type);
},
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 c78ca56e50b..2d27c7dc86d 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
@@ -8,7 +8,6 @@
<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">
-<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_expand_button/cr_expand_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
@@ -68,10 +67,15 @@
paper-spinner-lite {
@apply --cr-icon-height-width;
}
+
.warning {
color: var(--cr-secondary-text-color);
margin-inline-start: var(--settings-controlled-by-spacing);
}
+
+ #mac-address-container {
+ border-top: none;
+ }
</style>
<!-- Title section: Icon + name + connection state. -->
<div id="titleDiv" class="settings-box first">
@@ -83,9 +87,9 @@
<div id="networkState" class="title settings-box-text"
connected$="[[isConnectedState_(managedProperties_)]]"
error$="[[isConnectionErrorState_(
- managedProperties_, outOfRange_)]]">
+ managedProperties_, outOfRange_, deviceState_)]]">
[[getStateText_(managedProperties_, propertiesReceived_,
- outOfRange_)]]
+ outOfRange_, deviceState_)]]
</div>
<template is="dom-if"
if="[[isPolicySource(managedProperties_.source))]]">
@@ -118,17 +122,18 @@
</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_"
+ <controlled-button id="connect" class="action-button"
+ on-click="onConnectTap_"
hidden$="[[!showConnect_(managedProperties_, globalPolicy,
- managedNetworkAvailable)]]"
+ managedNetworkAvailable, deviceState_)]]"
disabled="[[!enableConnect_(managedProperties_, defaultNetwork,
propertiesReceived_, outOfRange_, globalPolicy,
- managedNetworkAvailable)]]"
+ managedNetworkAvailable, deviceState_)]]"
label="$i18n{networkButtonConnect}"
pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_,
prefs.vpn_config_allowed)]]">
</controlled-button>
- <controlled-button id="disconnect" action-button
+ <controlled-button id="disconnect" class="action-button"
on-click="onDisconnectTap_"
hidden$="[[!showDisconnect_(managedProperties_)]]"
label="$i18n{networkButtonDisconnect}"
@@ -324,6 +329,7 @@
<!-- MAC Address. -->
<div class="settings-box two-line single-column stretch indented"
+ id="mac-address-container"
hidden$="[[!deviceState_.macAddress]]">
<div>$i18n{OncMacAddress}</div>
<div class="secondary">[[deviceState_.macAddress]]</div>
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 3dd71d9ff20..7c15915a2c8 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
@@ -104,12 +104,6 @@ Polymer({
},
/**
- * Interface for networkingPrivate calls, passed from internet_page.
- * @type {NetworkingPrivate}
- */
- networkingPrivate: Object,
-
- /**
* The network AutoConnect state as a fake preference object.
* @private {!chrome.settingsPrivate.PrefObject|undefined}
*/
@@ -205,12 +199,7 @@ Polymer({
/** @private {settings.InternetPageBrowserProxy} */
browserProxy_: null,
- /**
- * 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.CrosNetworkConfigRemote}
- */
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
networkConfig_: null,
/** @override */
@@ -355,10 +344,9 @@ Polymer({
if (!this.didSetFocus_) {
// Focus a button once the initial state is set.
this.didSetFocus_ = true;
- const button = this.$$('#titleDiv .action-button:not([hidden])') ||
- this.$$('#titleDiv cr-button:not([hidden])');
+ const button = this.$$('#titleDiv .action-button:not([hidden])');
if (button) {
- setTimeout(() => button.focus());
+ Polymer.RenderStatus.afterNextRender(this, () => button.focus());
}
}
@@ -389,7 +377,7 @@ Polymer({
if (!this.propertiesReceived_) {
return;
}
- const config = {};
+ const config = this.getDefaultConfigProperties_();
config.autoConnect = {value: !!this.autoConnectPref_.value};
this.setMojoNetworkProperties_(config);
},
@@ -441,7 +429,7 @@ Polymer({
if (!this.propertiesReceived_) {
return;
}
- const config = {};
+ const config = this.getDefaultConfigProperties_();
config.priority = {value: this.preferNetwork_ ? 1 : 0};
this.setMojoNetworkProperties_(config);
},
@@ -451,7 +439,7 @@ Polymer({
const filter = {
filter: mojom.FilterType.kVisible,
networkType: mojom.NetworkType.kAll,
- limit: mojom.kNoLimit,
+ limit: mojom.NO_LIMIT,
};
this.networkConfig_.getNetworkState(this.guid).then(response => {
if (response.result) {
@@ -522,10 +510,25 @@ Polymer({
this.close();
return;
}
+
const managedProperties = OncMojo.getDefaultManagedProperties(
networkState.type, networkState.guid, networkState.name);
managedProperties.connectable = networkState.connectable;
managedProperties.connectionState = networkState.connectionState;
+ switch (networkState.type) {
+ case mojom.NetworkType.kCellular:
+ managedProperties.typeProperties.cellular.signalStrength =
+ networkState.typeState.cellular.signalStrength;
+ break;
+ case mojom.NetworkType.kTether:
+ managedProperties.typeProperties.tether.signalStrength =
+ networkState.typeState.tether.signalStrength;
+ break;
+ case mojom.NetworkType.kWiFi:
+ managedProperties.typeProperties.wifi.signalStrength =
+ networkState.typeState.wifi.signalStrength;
+ break;
+ }
this.managedProperties_ = managedProperties;
this.propertiesReceived_ = true;
@@ -544,6 +547,14 @@ Polymer({
},
/**
+ * @return {!mojom.ConfigProperties}
+ * @private
+ */
+ getDefaultConfigProperties_: function() {
+ return OncMojo.getDefaultConfigProperties(this.managedProperties_.type);
+ },
+
+ /**
* @param {!mojom.ConfigProperties} config
* @private
*/
@@ -565,15 +576,17 @@ Polymer({
* @param {!mojom.ManagedProperties} managedProperties
* @param {boolean} propertiesReceived
* @param {boolean} outOfRange
+ * @param {?OncMojo.DeviceStateProperties} deviceState
* @return {string} The text to display for the network connection state.
* @private
*/
- getStateText_: function(managedProperties, propertiesReceived, outOfRange) {
+ getStateText_: function(
+ managedProperties, propertiesReceived, outOfRange, deviceState) {
if (!managedProperties || !propertiesReceived) {
return '';
}
- if (outOfRange) {
+ if (this.isOutOfRangeOrNotEnabled_(outOfRange, deviceState)) {
return managedProperties.type == mojom.NetworkType.kTether ?
this.i18n('tetherPhoneOutOfRange') :
this.i18n('networkOutOfRange');
@@ -581,11 +594,11 @@ Polymer({
if (managedProperties.type == mojom.NetworkType.kCellular &&
!managedProperties.connectable) {
- if (managedProperties.cellular.homeProvider &&
- managedProperties.cellular.homeProvider.name) {
+ if (managedProperties.typeProperties.cellular.homeProvider &&
+ managedProperties.typeProperties.cellular.homeProvider.name) {
return this.i18n(
'cellularContactSpecificCarrier',
- managedProperties.cellular.homeProvider.name);
+ managedProperties.typeProperties.cellular.homeProvider.name);
}
return this.i18n('cellularContactDefaultCarrier');
}
@@ -614,11 +627,11 @@ Polymer({
if (!this.isCellular_(managedProperties)) {
return '';
}
- if (!managedProperties.cellular.allowRoaming) {
+ if (!managedProperties.typeProperties.cellular.allowRoaming) {
return this.i18n('networkAllowDataRoamingDisabled');
}
- return managedProperties.cellular.roamingState == 'Roaming' ?
+ return managedProperties.typeProperties.cellular.roamingState == 'Roaming' ?
this.i18n('networkAllowDataRoamingEnabledRoaming') :
this.i18n('networkAllowDataRoamingEnabledHome');
},
@@ -636,11 +649,13 @@ Polymer({
/**
* @param {!mojom.ManagedProperties|undefined} managedProperties
* @param {boolean} outOfRange
+ * @param {?OncMojo.DeviceStateProperties} deviceState
* @return {boolean} True if the network shown cannot initiate a connection.
* @private
*/
- isConnectionErrorState_: function(managedProperties, outOfRange) {
- if (outOfRange) {
+ isConnectionErrorState_: function(
+ managedProperties, outOfRange, deviceState) {
+ if (this.isOutOfRangeOrNotEnabled_(outOfRange, deviceState)) {
return true;
}
@@ -710,7 +725,8 @@ Polymer({
this.isPolicySource(managedProperties.source)) {
return false;
}
- const hexSsid = OncMojo.getActiveString(managedProperties.wifi.hexSsid);
+ const hexSsid =
+ OncMojo.getActiveString(managedProperties.typeProperties.wifi.hexSsid);
return !!globalPolicy.allowOnlyPolicyNetworksToConnect ||
(!!globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable &&
!!managedNetworkAvailable) ||
@@ -722,11 +738,12 @@ Polymer({
* @param {!mojom.ManagedProperties} managedProperties
* @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
+ * @param {?OncMojo.DeviceStateProperties} deviceState
* @return {boolean}
* @private
*/
showConnect_: function(
- managedProperties, globalPolicy, managedNetworkAvailable) {
+ managedProperties, globalPolicy, managedNetworkAvailable, deviceState) {
if (!managedProperties) {
return false;
}
@@ -741,15 +758,24 @@ Polymer({
if (this.isArcVpn_(managedProperties)) {
return false;
}
+
if (managedProperties.connectionState !=
mojom.ConnectionStateType.kNotConnected) {
return false;
}
+
+ if (deviceState &&
+ deviceState.deviceState !=
+ chromeos.networkConfig.mojom.DeviceStateType.kEnabled) {
+ 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;
@@ -801,7 +827,8 @@ Polymer({
if (!this.isCellular_(managedProperties)) {
return false;
}
- const activation = managedProperties.cellular.activationState;
+ const activation =
+ managedProperties.typeProperties.cellular.activationState;
return activation == mojom.ActivationStateType.kNotActivated ||
activation == mojom.ActivationStateType.kPartiallyActivated;
},
@@ -828,7 +855,8 @@ Polymer({
return false;
}
if (type == mojom.NetworkType.kWiFi &&
- managedProperties.wifi.security == mojom.SecurityType.kNone) {
+ managedProperties.typeProperties.wifi.security ==
+ mojom.SecurityType.kNone) {
return false;
}
if (type == mojom.NetworkType.kWiFi &&
@@ -916,18 +944,20 @@ Polymer({
return false;
}
- const paymentPortal = managedProperties.cellular.paymentPortal;
+ const paymentPortal =
+ managedProperties.typeProperties.cellular.paymentPortal;
if (!paymentPortal || !paymentPortal.url) {
return false;
}
// Only show for connected networks or LTE networks with a valid MDN.
if (!this.isConnectedState_(managedProperties)) {
- const technology = managedProperties.cellular.networkTechnology;
+ const technology =
+ managedProperties.typeProperties.cellular.networkTechnology;
if (technology != 'LTE' && technology != 'LTEAdvanced') {
return false;
}
- if (!managedProperties.cellular.mdn) {
+ if (!managedProperties.typeProperties.cellular.mdn) {
return false;
}
}
@@ -942,14 +972,16 @@ Polymer({
* @param {boolean} outOfRange
* @param {!mojom.GlobalPolicy} globalPolicy
* @param {boolean} managedNetworkAvailable
+ * @param {?OncMojo.DeviceStateProperties} deviceState
* @return {boolean} Whether or not to enable the network connect button.
* @private
*/
enableConnect_: function(
managedProperties, defaultNetwork, propertiesReceived, outOfRange,
- globalPolicy, managedNetworkAvailable) {
+ globalPolicy, managedNetworkAvailable, deviceState) {
if (!this.showConnect_(
- managedProperties, globalPolicy, managedNetworkAvailable)) {
+ managedProperties, globalPolicy, managedNetworkAvailable,
+ deviceState)) {
return false;
}
if (!propertiesReceived || outOfRange) {
@@ -1017,7 +1049,7 @@ Polymer({
/** @private */
onConnectTap_: function() {
if (this.managedProperties_.type == mojom.NetworkType.kTether &&
- (!this.managedProperties_.tether.hasConnectedToHost)) {
+ (!this.managedProperties_.typeProperties.tether.hasConnectedToHost)) {
this.showTetherDialog_();
return;
}
@@ -1054,9 +1086,13 @@ Polymer({
/** @private */
onForgetTap_: function() {
- this.networkingPrivate.forgetNetwork(this.guid);
- // A forgotten network no longer has a valid GUID, close the subpage.
- this.close();
+ this.networkConfig_.forgetNetwork(this.guid).then(response => {
+ if (!response.success) {
+ console.error('Froget network failed for: ' + this.guid);
+ }
+ // A forgotten network no longer has a valid GUID, close the subpage.
+ this.close();
+ });
},
/** @private */
@@ -1102,8 +1138,9 @@ Polymer({
return loadTimeData.getBoolean('showHiddenNetworkWarning') &&
!!this.autoConnectPref_ && !!this.autoConnectPref_.value &&
!!this.managedProperties_ &&
- !!this.managedProperties_.type == mojom.NetworkType.kWiFi &&
- !!OncMojo.getActiveValue(this.managedProperties_.wifi.hiddenSsid);
+ this.managedProperties_.type == mojom.NetworkType.kWiFi &&
+ !!OncMojo.getActiveValue(
+ this.managedProperties_.typeProperties.wifi.hiddenSsid);
},
/**
@@ -1120,7 +1157,7 @@ Polymer({
}
const field = e.detail.field;
const value = e.detail.value;
- const config = {};
+ const config = this.getDefaultConfigProperties_();
const valueType = typeof value;
if (valueType != 'string' && valueType != 'number' &&
valueType != 'boolean' && !Array.isArray(value)) {
@@ -1130,10 +1167,17 @@ Polymer({
return;
}
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;
+ // Ensure that any required configuration properties for partial
+ // configurations are set.
+ const vpnConfig = config.typeConfig.vpn;
+ if (vpnConfig) {
+ vpnConfig.type = this.managedProperties_.typeProperties.vpn.type;
+ if (vpnConfig.openVpn && vpnConfig.openVpn.saveCredentials == undefined) {
+ vpnConfig.openVpn.saveCredentials = false;
+ }
+ if (vpnConfig.l2tp && vpnConfig.l2tp.saveCredentials == undefined) {
+ vpnConfig.l2tp.saveCredentials = false;
+ }
}
this.setMojoNetworkProperties_(config);
},
@@ -1146,8 +1190,9 @@ Polymer({
if (!this.propertiesReceived_) {
return;
}
+ const config = this.getDefaultConfigProperties_();
const apn = event.detail;
- const config = {cellular: {apn: apn}};
+ config.typeConfig.cellular = {apn: apn};
this.setMojoNetworkProperties_(config);
},
@@ -1180,7 +1225,9 @@ Polymer({
if (!this.propertiesReceived_) {
return;
}
- this.setMojoNetworkProperties_({proxySettings: event.detail});
+ const config = this.getDefaultConfigProperties_();
+ config.proxySettings = event.detail;
+ this.setMojoNetworkProperties_(config);
},
/**
@@ -1226,7 +1273,7 @@ Polymer({
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 &&
- OncMojo.getActiveValue(managedProperties.vpn.host) ===
+ OncMojo.getActiveValue(managedProperties.typeProperties.vpn.host) ===
this.prefs.arc.vpn.always_on.vpn_package.value;
},
@@ -1289,7 +1336,8 @@ Polymer({
*/
hasVisibleFields_: function(fields) {
for (let i = 0; i < fields.length; ++i) {
- const value = this.get(fields[i], this.managedProperties_);
+ const key = OncMojo.getManagedPropertyKey(fields[i]);
+ const value = this.get(key, this.managedProperties_);
if (value !== undefined && value !== '') {
return true;
}
@@ -1316,39 +1364,44 @@ Polymer({
}
/** @type {!Array<string>} */ const fields = [];
- 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 == mojom.NetworkType.kVPN) {
- const vpnType = this.managedProperties_.vpn.type;
- switch (vpnType) {
- case mojom.VpnType.kExtension:
- fields.push('vpn.providerName');
- break;
- case mojom.VpnType.kArc:
- fields.push('vpn.type');
- fields.push('vpn.providerName');
- break;
- case mojom.VpnType.kOpenVPN:
- fields.push(
- 'vpn.type', 'vpn.host', 'vpn.openVpn.username',
- 'vpn.openVpn.extraHosts');
- break;
- case mojom.VpnType.kL2TPIPsec:
- fields.push('vpn.type', 'vpn.host', 'vpn.l2tp.username');
- break;
- }
- } else if (type == mojom.NetworkType.kWiFi) {
- if (this.managedProperties_.restrictedConnectivity) {
- fields.push('restrictedConnectivity');
- }
+ switch (this.managedProperties_.type) {
+ case mojom.NetworkType.kCellular:
+ fields.push(
+ 'cellular.activationState', 'cellular.servingOperator.name');
+ if (this.managedProperties_.restrictedConnectivity) {
+ fields.push('restrictedConnectivity');
+ }
+ break;
+ case mojom.NetworkType.kTether:
+ fields.push(
+ 'tether.batteryPercentage', 'tether.signalStrength',
+ 'tether.carrier');
+ break;
+ case mojom.NetworkType.kVPN:
+ const vpnType = this.managedProperties_.typeProperties.vpn.type;
+ switch (vpnType) {
+ case mojom.VpnType.kExtension:
+ fields.push('vpn.providerName');
+ break;
+ case mojom.VpnType.kArc:
+ fields.push('vpn.type');
+ fields.push('vpn.providerName');
+ break;
+ case mojom.VpnType.kOpenVPN:
+ fields.push(
+ 'vpn.type', 'vpn.host', 'vpn.openVpn.username',
+ 'vpn.openVpn.extraHosts');
+ break;
+ case mojom.VpnType.kL2TPIPsec:
+ fields.push('vpn.type', 'vpn.host', 'vpn.l2tp.username');
+ break;
+ }
+ break;
+ case mojom.NetworkType.kWiFi:
+ if (this.managedProperties_.restrictedConnectivity) {
+ fields.push('restrictedConnectivity');
+ }
+ break;
}
return fields;
},
@@ -1368,7 +1421,7 @@ Polymer({
/** @dict */ const editFields = {};
const type = this.managedProperties_.type;
if (type == mojom.NetworkType.kVPN) {
- const vpnType = this.managedProperties_.vpn.type;
+ const vpnType = this.managedProperties_.typeProperties.vpn.type;
if (vpnType != mojom.VpnType.kExtension) {
editFields['vpn.host'] = 'String';
}
@@ -1391,15 +1444,19 @@ Polymer({
/** @type {!Array<string>} */ const fields = [];
const type = this.managedProperties_.type;
- if (type == mojom.NetworkType.kCellular) {
- fields.push(
- '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');
+ switch (type) {
+ case mojom.NetworkType.kCellular:
+ fields.push(
+ 'cellular.family', 'cellular.networkTechnology',
+ 'cellular.servingOperator.code');
+ break;
+ case 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');
+ break;
}
return fields;
},
@@ -1520,7 +1577,7 @@ Polymer({
showCellularChooseNetwork_: function(managedProperties) {
return !!managedProperties &&
managedProperties.type == mojom.NetworkType.kCellular &&
- managedProperties.cellular.supportNetworkScan;
+ managedProperties.typeProperties.cellular.supportNetworkScan;
},
/**
@@ -1543,7 +1600,7 @@ Polymer({
showCellularSim_: function(managedProperties) {
return !!managedProperties &&
managedProperties.type == mojom.NetworkType.kCellular &&
- managedProperties.cellular.family != 'CDMA';
+ managedProperties.typeProperties.cellular.family != 'CDMA';
},
/**
@@ -1554,7 +1611,7 @@ Polymer({
isArcVpn_: function(managedProperties) {
return !!managedProperties &&
managedProperties.type == mojom.NetworkType.kVPN &&
- managedProperties.vpn.type == mojom.VpnType.kArc;
+ managedProperties.typeProperties.vpn.type == mojom.VpnType.kArc;
},
/**
@@ -1565,7 +1622,7 @@ Polymer({
isThirdPartyVpn_: function(managedProperties) {
return !!managedProperties &&
managedProperties.type == mojom.NetworkType.kVPN &&
- managedProperties.vpn.type == mojom.VpnType.kExtension;
+ managedProperties.typeProperties.vpn.type == mojom.VpnType.kExtension;
},
/**
@@ -1608,5 +1665,18 @@ Polymer({
}
return true;
},
+
+ /**
+ * @param {boolean} outOfRange
+ * @param {?OncMojo.DeviceStateProperties} deviceState
+ * @return {boolean}
+ * @private
+ */
+ isOutOfRangeOrNotEnabled_: function(outOfRange, deviceState) {
+ return outOfRange ||
+ (!!deviceState &&
+ deviceState.deviceState !=
+ chromeos.networkConfig.mojom.DeviceStateType.kEnabled);
+ },
});
})();
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 2e42c952c87..3351442766d 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
@@ -18,20 +18,14 @@ Polymer({
properties: {
/**
* The type of networks to list.
- * @type {CrOnc.Type}
+ * @type {chromeos.networkConfig.mojom.NetworkType|undefined}
*/
networkType: {
- type: String,
+ type: Number,
observer: 'networkTypeChanged_',
},
/**
- * Interface for networkingPrivate calls, passed from internet_page.
- * @type {NetworkingPrivate}
- */
- networkingPrivate: Object,
-
- /**
* List of all network state data for the network type.
* @private {!Array<!OncMojo.NetworkStateProperties>}
*/
@@ -60,12 +54,7 @@ Polymer({
/** @private {string} */
selectedGuid_: '',
- /**
- * 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.CrosNetworkConfigRemote}
- */
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
networkConfig_: null,
/** @override */
@@ -90,13 +79,13 @@ Polymer({
* @private
*/
refreshNetworks_: function() {
- if (!this.networkType) {
+ if (this.networkType === undefined) {
return;
}
const filter = {
filter: chromeos.networkConfig.mojom.FilterType.kConfigured,
- limit: chromeos.networkConfig.mojom.kNoLimit,
- networkType: OncMojo.getNetworkTypeFromString(this.networkType),
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
+ networkType: this.networkType,
};
this.networkConfig_.getNetworkStateList(filter).then(response => {
this.networkStateList_ = response.result;
@@ -201,19 +190,29 @@ Polymer({
/** @private */
onRemovePreferredTap_: function() {
- this.setProperties_({priority: {value: 0}});
+ assert(this.networkType !== undefined);
+ const config = OncMojo.getDefaultConfigProperties(this.networkType);
+ config.priority = {value: 0};
+ this.setProperties_(config);
/** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close();
},
/** @private */
onAddPreferredTap_: function() {
- this.setProperties_({priority: {value: 1}});
+ assert(this.networkType !== undefined);
+ const config = OncMojo.getDefaultConfigProperties(this.networkType);
+ config.priority = {value: 1};
+ this.setProperties_(config);
/** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close();
},
/** @private */
onForgetTap_: function() {
- this.networkingPrivate.forgetNetwork(this.selectedGuid_);
+ this.networkConfig_.forgetNetwork(this.selectedGuid_).then(response => {
+ if (!response.success) {
+ console.error('Froget network failed for: ' + this.selectedGuid_);
+ }
+ });
/** @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 10eeff05b0a..f9b99636a51 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -1,7 +1,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<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_onc_types.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_expand_button/cr_expand_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/icons.html">
@@ -49,13 +49,12 @@
</cr-expand-button>
<template is="dom-if" if="[[addConnectionExpanded_]]">
<div class="list-frame vertical-list">
- <template is="dom-if"
- if="[[deviceIsEnabled_(deviceStates, 'WiFi')]]">
+ <template is="dom-if" if="[[wifiIsEnabled_(deviceStates)]]">
<div actionable class="list-item" on-click="onAddWiFiTap_">
<div class="start settings-box-text">
$i18n{internetAddWiFi}
</div>
- <cr-icon-button class$="[[getAddNetworkClass_('WiFi')]]"
+ <cr-icon-button class="icon-add-wifi"
aria-label="$i18n{internetAddWiFi}"></cr-icon-button>
</div>
</template>
@@ -63,7 +62,7 @@
<div class="start settings-box-text">
$i18n{internetAddVPN}
</div>
- <cr-icon-button class$="[[getAddNetworkClass_('VPN')]]"
+ <cr-icon-button class="icon-add-circle"
aria-label="$i18n{internetAddVPN}"></cr-icon-button>
</div>
<template is="dom-repeat" items="[[vpnProviders_]]">
@@ -96,7 +95,6 @@
<settings-internet-detail-page prefs="{{prefs}}"
default-network="[[defaultNetwork]]"
global-policy="[[globalPolicy_]]"
- networking-private="[[networkingPrivate]]"
managed-network-available="[[managedNetworkAvailable]]">
</settings-internet-detail-page>
</settings-subpage>
@@ -105,8 +103,7 @@
<template is="dom-if" route-path="/knownNetworks" no-search restamp>
<settings-subpage page-title="$i18n{internetKnownNetworksPageTitle}">
<settings-internet-known-networks-page
- network-type="[[knownNetworksType_]]"
- networking-private="[[networkingPrivate]]">
+ network-type="[[knownNetworksType_]]">
</settings-internet-known-networks-page>
</settings-subpage>
</template>
@@ -128,10 +125,10 @@
</settings-animated-pages>
- <internet-config id="configDialog"
- networking-private="[[networkingPrivate]]"
- global-policy="[[globalPolicy_]]">
- </internet-config>
+ <template is="dom-if" if="[[showInternetConfig_]]" restamp>
+ <internet-config id="configDialog" on-close="onInternetConfigClose_">
+ </internet-config>
+ </template>
</template>
<script src="internet_page.js"></script>
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 1737c822b40..8f2b2d7b745 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -22,14 +22,6 @@ Polymer({
],
properties: {
- /**
- * Interface for networkingPrivate calls. May be overriden by tests.
- * @type {NetworkingPrivate}
- */
- networkingPrivate: {
- type: Object,
- value: chrome.networkingPrivate,
- },
/** Preferences state. */
prefs: {
@@ -65,16 +57,18 @@ Polymer({
showSpinner_: Boolean,
/**
- * The network type for the networks subpage. Used in the subpage header.
+ * The network type for the networks subpage when shown.
+ * @type {chromeos.networkConfig.mojom.NetworkType}
* @private
*/
- subpageType_: String,
+ subpageType_: Number,
/**
- * The network type for the known networks subpage.
+ * The network type for the known networks subpage when shown.
+ * @type {chromeos.networkConfig.mojom.NetworkType}
* @private
*/
- knownNetworksType_: String,
+ knownNetworksType_: Number,
/**
* Whether the 'Add connection' section is expanded.
@@ -109,6 +103,12 @@ Polymer({
}
},
+ /** @private {boolean} */
+ showInternetConfig_: {
+ type: Boolean,
+ value: false,
+ },
+
/** @private {!Map<string, Element>} */
focusConfig_: {
type: Object,
@@ -118,8 +118,11 @@ Polymer({
},
},
- /** @private {string} Type of last detail page visited. */
- detailType_: '',
+ /**
+ * Type of last detail page visited
+ * @private {chromeos.networkConfig.mojom.NetworkType|undefined}
+ */
+ detailType_: undefined,
// Element event listeners
listeners: {
@@ -134,12 +137,7 @@ Polymer({
/** @private {?settings.InternetPageBrowserProxy} */
browserProxy_: null,
- /**
- * 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.CrosNetworkConfigRemote}
- */
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
networkConfig_: null,
/** @override */
@@ -170,7 +168,7 @@ Polymer({
const queryParams = settings.getQueryParameters();
const type = queryParams.get('type');
if (type) {
- this.subpageType_ = type;
+ this.subpageType_ = OncMojo.getNetworkTypeFromString(type);
}
} else if (route == settings.routes.KNOWN_NETWORKS) {
// Handle direct navigation to the known networks page,
@@ -178,7 +176,7 @@ Polymer({
const queryParams = settings.getQueryParameters();
const type = queryParams.get('type');
if (type) {
- this.knownNetworksType_ = type;
+ this.knownNetworksType_ = OncMojo.getNetworkTypeFromString(type);
}
} else if (
route != settings.routes.INTERNET && route != settings.routes.BASIC) {
@@ -201,9 +199,9 @@ Polymer({
if (subPage) {
element = subPage.$$('#networkList');
}
- } else if (this.detailType_) {
- const rowForDetailType =
- this.$$('network-summary').$$(`#${this.detailType_}`);
+ } else if (this.detailType_ !== undefined) {
+ const oncType = OncMojo.getNetworkTypeString(this.detailType_);
+ const rowForDetailType = this.$$('network-summary').$$(`#${oncType}`);
// Note: It is possible that the row is no longer present in the DOM
// (e.g., when a Cellular dongle is unplugged or when Instant Tethering
@@ -219,7 +217,7 @@ Polymer({
}
},
- /** CrosNetworkConfigObserver impl */
+ /** CrNetworkListenerBehavior override */
onVpnProvidersChanged: function() {
this.networkConfig_.getVpnProviders().then(response => {
const providers = response.providers;
@@ -246,33 +244,48 @@ Polymer({
* @private
*/
onShowConfig_: function(event) {
+ const type = OncMojo.getNetworkTypeFromString(event.detail.type);
if (!event.detail.guid) {
// New configuration
- this.showConfig_(true /* configAndConnect */, event.detail.type);
+ this.showConfig_(true /* configAndConnect */, type);
} else {
this.showConfig_(
- false /* configAndConnect */, event.detail.type, event.detail.guid,
+ false /* configAndConnect */, type, event.detail.guid,
event.detail.name);
}
},
/**
* @param {boolean} configAndConnect
- * @param {string} type
+ * @param {chromeos.networkConfig.mojom.NetworkType} type
* @param {?string=} opt_guid
* @param {?string=} opt_name
* @private
*/
showConfig_: function(configAndConnect, type, opt_guid, opt_name) {
- assert(type != CrOnc.Type.CELLULAR && type != CrOnc.Type.TETHER);
- const configDialog =
- /** @type {!InternetConfigElement} */ (this.$.configDialog);
- configDialog.type =
- /** @type {chrome.networkingPrivate.NetworkType} */ (type);
- configDialog.guid = opt_guid || '';
- configDialog.name = opt_name || '';
- configDialog.showConnect = configAndConnect;
- configDialog.open();
+ assert(
+ type != chromeos.networkConfig.mojom.NetworkType.kCellular &&
+ type != chromeos.networkConfig.mojom.NetworkType.kTether);
+ if (this.showInternetConfig_) {
+ return;
+ }
+ this.showInternetConfig_ = true;
+ // Async call to ensure dialog is stamped.
+ setTimeout(() => {
+ const configDialog =
+ /** @type {!InternetConfigElement} */ (this.$$('#configDialog'));
+ assert(!!configDialog);
+ configDialog.type = OncMojo.getNetworkTypeString(type);
+ configDialog.guid = opt_guid || '';
+ configDialog.name = opt_name || '';
+ configDialog.showConnect = configAndConnect;
+ configDialog.open();
+ });
+ },
+
+ /** @private */
+ onInternetConfigClose_: function() {
+ this.showInternetConfig_ = false;
},
/**
@@ -281,11 +294,10 @@ Polymer({
*/
onShowDetail_: function(event) {
const networkState = event.detail;
- const oncType = OncMojo.getNetworkTypeString(networkState.type);
- this.detailType_ = oncType;
+ this.detailType_ = networkState.type;
const params = new URLSearchParams;
params.append('guid', networkState.guid);
- params.append('type', oncType);
+ params.append('type', OncMojo.getNetworkTypeString(networkState.type));
params.append('name', OncMojo.getNetworkStateDisplayName(networkState));
settings.navigateTo(settings.routes.NETWORK_DETAIL, params);
},
@@ -306,39 +318,31 @@ Polymer({
// The shared Cellular/Tether subpage is referred to as "Mobile".
// TODO(khorimoto): Remove once Cellular/Tether are split into their own
// sections.
- if (this.subpageType_ == CrOnc.Type.CELLULAR ||
- this.subpageType_ == CrOnc.Type.TETHER) {
+ if (this.subpageType_ == mojom.NetworkType.kCellular ||
+ this.subpageType_ == mojom.NetworkType.kTether) {
return this.i18n('OncTypeMobile');
}
- return this.i18n('OncType' + this.subpageType_);
- },
-
- /**
- * @param {string} type
- * @return {string}
- * @private
- */
- getAddNetworkClass_: function(type) {
- return type == CrOnc.Type.WI_FI ? 'icon-add-wifi' : 'icon-add-circle';
+ return this.i18n(
+ 'OncType' + OncMojo.getNetworkTypeString(this.subpageType_));
},
/**
- * @param {string} subpageType
+ * @param {chromeos.networkConfig.mojom.NetworkType} subpageType
* @param {!Object<!OncMojo.DeviceStateProperties>|undefined} deviceStates
* @return {!OncMojo.DeviceStateProperties|undefined}
* @private
*/
getDeviceState_: function(subpageType, deviceStates) {
- if (!subpageType) {
+ if (subpageType === undefined) {
return undefined;
}
// If both Tether and Cellular are enabled, use the Cellular device state
// when directly navigating to the Tether page.
- if (subpageType == CrOnc.Type.TETHER &&
+ if (subpageType == mojom.NetworkType.kTether &&
this.deviceStates[mojom.NetworkType.kCellular]) {
- subpageType = CrOnc.Type.CELLULAR;
+ subpageType = mojom.NetworkType.kCellular;
}
- return deviceStates[OncMojo.getNetworkTypeFromString(subpageType)];
+ return deviceStates[subpageType];
},
/**
@@ -356,7 +360,8 @@ Polymer({
* @private
*/
onDeviceStatesChanged_: function(newValue, oldValue) {
- const wifiDeviceState = this.getDeviceState_(CrOnc.Type.WI_FI, newValue);
+ const wifiDeviceState =
+ this.getDeviceState_(mojom.NetworkType.kWiFi, newValue);
let managedNetworkAvailable = false;
if (wifiDeviceState) {
managedNetworkAvailable = !!wifiDeviceState.managedNetworkAvailable;
@@ -366,9 +371,7 @@ Polymer({
this.managedNetworkAvailable = managedNetworkAvailable;
}
- if (this.detailType_ &&
- !this.deviceStates[OncMojo.getNetworkTypeFromString(
- this.detailType_)]) {
+ if (this.detailType_ && !this.deviceStates[this.detailType_]) {
// If the device type associated with the current network has been
// removed (e.g., due to unplugging a Cellular dongle), the details page,
// if visible, displays controls which are no longer functional. If this
@@ -385,22 +388,26 @@ Polymer({
* @private
*/
onShowKnownNetworks_: function(event) {
- const oncType = OncMojo.getNetworkTypeString(event.detail);
- this.detailType_ = oncType;
- this.knownNetworksType_ = oncType;
+ const type = event.detail;
+ this.detailType_ = type;
+ this.knownNetworksType_ = type;
const params = new URLSearchParams;
- params.append('type', oncType);
+ params.append('type', OncMojo.getNetworkTypeString(type));
settings.navigateTo(settings.routes.KNOWN_NETWORKS, params);
},
/** @private */
onAddWiFiTap_: function() {
- this.showConfig_(true /* configAndConnect */, CrOnc.Type.WI_FI);
+ this.showConfig_(
+ true /* configAndConnect */,
+ chromeos.networkConfig.mojom.NetworkType.kWiFi);
},
/** @private */
onAddVPNTap_: function() {
- this.showConfig_(true /* configAndConnect */, CrOnc.Type.VPN);
+ this.showConfig_(
+ true /* configAndConnect */,
+ chromeos.networkConfig.mojom.NetworkType.kVPN);
},
/**
@@ -417,11 +424,10 @@ Polymer({
* @private
*/
showNetworksSubpage_: function(type) {
- const oncType = OncMojo.getNetworkTypeString(type);
- this.detailType_ = oncType;
+ this.detailType_ = type;
const params = new URLSearchParams;
- params.append('type', oncType);
- this.subpageType_ = oncType;
+ params.append('type', OncMojo.getNetworkTypeString(type));
+ this.subpageType_ = type;
settings.navigateTo(settings.routes.INTERNET_NETWORKS, params);
},
@@ -452,14 +458,13 @@ Polymer({
/**
* @param {!Array<!OncMojo.DeviceStateProperties>} deviceStates
- * @param {string} type
* @return {boolean}
* @private
*/
- deviceIsEnabled_: function(deviceStates, type) {
- const device = deviceStates[OncMojo.getNetworkTypeFromString(type)];
- return !!device &&
- device.deviceState ==
+ wifiIsEnabled_: function(deviceStates) {
+ const wifi = deviceStates[mojom.NetworkType.kWiFi];
+ return !!wifi &&
+ wifi.deviceState ==
chromeos.networkConfig.mojom.DeviceStateType.kEnabled;
},
@@ -497,15 +502,15 @@ Polymer({
*/
onNetworkConnect_: function(event) {
const networkState = event.detail.networkState;
- const oncType = OncMojo.getNetworkTypeString(networkState.type);
+ const type = networkState.type;
const displayName = OncMojo.getNetworkStateDisplayName(networkState);
if (!event.detail.bypassConnectionDialog &&
- networkState.type == mojom.NetworkType.kTether &&
- !networkState.tether.hasConnectedToHost) {
+ type == mojom.NetworkType.kTether &&
+ !networkState.typeState.tether.hasConnectedToHost) {
const params = new URLSearchParams;
params.append('guid', networkState.guid);
- params.append('type', oncType);
+ params.append('type', OncMojo.getNetworkTypeString(type));
params.append('name', displayName);
params.append('showConfigure', true.toString());
@@ -513,10 +518,10 @@ Polymer({
return;
}
- const isMobile = OncMojo.networkTypeIsMobile(networkState.type);
+ const isMobile = OncMojo.networkTypeIsMobile(type);
if (!isMobile && (!networkState.connectable || !!networkState.errorState)) {
this.showConfig_(
- true /* configAndConnect */, oncType, networkState.guid, displayName);
+ true /* configAndConnect */, type, networkState.guid, displayName);
return;
}
@@ -532,7 +537,7 @@ Polymer({
case mojom.StartConnectResult.kNotConfigured:
if (!isMobile) {
this.showConfig_(
- true /* configAndConnect */, oncType, networkState.guid,
+ true /* configAndConnect */, type, networkState.guid,
displayName);
}
return;
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 9996d3b6538..8ce6c994e2f 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js
@@ -120,12 +120,7 @@ Polymer({
/** @private {settings.InternetPageBrowserProxy} */
browserProxy_: null,
- /**
- * 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.CrosNetworkConfigRemote}
- */
+ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
networkConfig_: null,
/** @override */
@@ -275,7 +270,7 @@ Polymer({
}
const filter = {
filter: chromeos.networkConfig.mojom.FilterType.kVisible,
- limit: chromeos.networkConfig.mojom.kNoLimit,
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
networkType: this.deviceState.type,
};
this.networkConfig_.getNetworkStateList(filter).then(response => {
@@ -298,7 +293,7 @@ Polymer({
this.tetherDeviceState) {
const filter = {
filter: chromeos.networkConfig.mojom.FilterType.kVisible,
- limit: chromeos.networkConfig.mojom.kNoLimit,
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
networkType: mojom.NetworkType.kTether,
};
this.networkConfig_.getNetworkStateList(filter).then(response => {
@@ -314,7 +309,7 @@ Polymer({
const thirdPartyVpns = {};
networkStates.forEach(state => {
assert(state.type == mojom.NetworkType.kVPN);
- switch (state.vpn.type) {
+ switch (state.typeState.vpn.type) {
case mojom.VpnType.kL2TPIPsec:
case mojom.VpnType.kOpenVPN:
builtinNetworkStates.push(state);
@@ -326,7 +321,7 @@ Polymer({
}
// Otherwise Arc VPNs are treated the same as Extension VPNs.
case mojom.VpnType.kExtension:
- const providerId = state.vpn.providerId;
+ const providerId = state.typeState.vpn.providerId;
thirdPartyVpns[providerId] = thirdPartyVpns[providerId] || [];
thirdPartyVpns[providerId].push(state);
break;
@@ -354,7 +349,7 @@ Polymer({
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 vpn = vpnList[0].typeState.vpn;
const provider = {
type: vpn.type,
providerId: vpn.providerId,
@@ -584,7 +579,8 @@ Polymer({
(!!this.globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable &&
!!this.deviceState && !!this.deviceState.managedNetworkAvailable) ||
(!!this.globalPolicy.blockedHexSsids &&
- this.globalPolicy.blockedHexSsids.includes(state.wifi.hexSsid));
+ this.globalPolicy.blockedHexSsids.includes(
+ state.typeState.wifi.hexSsid));
},
/**
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 a061a6e92ab..f44b433b079 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
@@ -1,7 +1,6 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_proxy.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/hidden_style_css.html">
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 3827c8cbf37..f04803663de 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
@@ -60,12 +60,12 @@ Polymer({
},
/**
- * @return {!OncMojo.ManagedProperty|undefined}
+ * @return {!mojom.ManagedString|undefined}
* @private
*/
getProxySettingsTypeProperty_: function() {
- return /** @type {!OncMojo.ManagedProperty|undefined} */ (
- this.get('proxySettings.type', this.managedProperties));
+ const proxySettings = this.managedProperties.proxySettings;
+ return proxySettings ? proxySettings.type : undefined;
},
/**
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 ac6a45c2d31..bc02417ee3e 100644
--- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
+++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js
@@ -149,7 +149,7 @@ Polymer({
getNetworkStates_: function(deviceStateList) {
const filter = {
filter: chromeos.networkConfig.mojom.FilterType.kVisible,
- limit: chromeos.networkConfig.mojom.kNoLimit,
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
networkType: mojom.NetworkType.kAll,
};
this.networkConfig_.getNetworkStateList(filter).then(response => {
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 5b26c96577a..4c6312d3dc0 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
@@ -2,7 +2,7 @@
<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_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_strings.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_toggle/cr_toggle.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
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 09cbcd3965e..7b26f618a41 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
@@ -132,7 +132,12 @@ Polymer({
const connectionState = networkState.connectionState;
const name = OncMojo.getNetworkStateDisplayName(networkState);
if (OncMojo.connectionStateIsConnected(connectionState)) {
- return name;
+ // Ethernet networks always have the display name 'Ethernet' so we use the
+ // state text 'Connected' to avoid repeating the label in the sublabel.
+ // See http://crbug.com/989907 for details.
+ return networkState.type == mojom.NetworkType.kEthernet ?
+ CrOncStrings.networkListItemConnected :
+ name;
}
if (connectionState == mojom.ConnectionStateType.kConnecting) {
return name ?
@@ -282,14 +287,22 @@ Polymer({
const type = deviceState.type;
if (type == mojom.NetworkType.kTether ||
(type == mojom.NetworkType.kCellular && this.tetherDeviceState)) {
- // The "Mobile data" subpage should always be shown if Tether networks are
+ // The "Mobile data" subpage should always be shown if Tether is
// available, even if there are currently no associated networks.
return true;
}
- const minlen =
- (type == mojom.NetworkType.kWiFi || type == mojom.NetworkType.kVPN) ?
- 1 :
- 2;
+ let minlen;
+ if (type == mojom.NetworkType.kVPN) {
+ // VPN subpage provides provider info so show if there are any networks.
+ minlen = 1;
+ } else if (type == mojom.NetworkType.kWiFi) {
+ // WiFi subpage includes 'Known Networks' so always show, even if the
+ // technology is still enabling / scanning, or none are visible.
+ minlen = 0;
+ } else {
+ // By default, only show the subpage if there are 2+ networks
+ minlen = 2;
+ }
return networkStateList.length >= minlen;
},
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 5a7c6beff6f..cce1a1de45c 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
@@ -79,27 +79,20 @@ Polymer({
* @private
*/
getBatteryPercentageAsString_: function(managedProperties) {
- const percentage = this.get('tether.batteryPercentage', managedProperties);
- if (percentage === undefined) {
- return '';
- }
- return percentage.toString();
+ return managedProperties.typeProperties.tether.batteryPercentage.toString();
},
/**
* Retrieves an image that corresponds to signal strength of the tether host.
* Custom icons are used here instead of a <cr-network-icon> because this
* dialog uses a special color scheme.
- *
* @param {!mojom.ManagedProperties} managedProperties
* @return {string} The name of the icon to be used to represent the network's
- * signal strength.
+ * signal strength.
*/
getSignalStrengthIconName_: function(managedProperties) {
- let signalStrength = this.get('tether.signalStrength', managedProperties);
- if (signalStrength === undefined) {
- signalStrength = 4;
- }
+ const signalStrength =
+ managedProperties.typeProperties.tether.signalStrength;
return 'os-settings:signal-cellular-' +
Math.min(4, Math.max(signalStrength, 0)) + '-bar';
},
diff --git a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
index c3732a62e48..a6905ca7fbf 100644
--- a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
+++ b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
@@ -56,9 +56,12 @@
scroll-target="[[subpageScrollTarget]]">
<template>
<div class="list-item">
- <div class="word text-elide">[[item]]</div>
+ <div id$="word[[index]]" class="word text-elide">[[item]]</div>
<cr-icon-button class="icon-clear" on-click="onRemoveWordTap_"
- tabindex$="[[tabIndex]]"></cr-icon-button>
+ tabindex$="[[tabIndex]]"
+ title="$i18n{deleteDictionaryWordButton}"
+ aria-describedby$="word[[index]]">
+ </cr-icon-button>
</div>
</template>
</iron-list>
diff --git a/chromium/chrome/browser/resources/settings/manifest.json b/chromium/chrome/browser/resources/settings/manifest.json
index c7a72e04e30..acbaa3c103e 100644
--- a/chromium/chrome/browser/resources/settings/manifest.json
+++ b/chromium/chrome/browser/resources/settings/manifest.json
@@ -1,5 +1,5 @@
{
- "name": "Settings",
+ "name": "$i18nRaw{name}",
"display": "standalone",
"icons": [
{
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn b/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn
index 7818234969e..a35e2871de8 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn
@@ -109,7 +109,6 @@ if (is_chromeos) {
":multidevice_feature_behavior",
"..: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/js/chromeos:onc_mojo",
]
externs_list = [ "$externs_path/networking_private.js" ]
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html
index 2e75dd98bd0..55a72bcb020 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html
@@ -31,10 +31,6 @@
#feature-items-container {
@apply --settings-list-frame-padding;
}
-
- #forget-device-container {
- border-top: var(--cr-separator-line);
- }
</style>
<div class="settings-box first">
<div id="status-text-container"
@@ -99,11 +95,17 @@
</template>
</div>
</template>
- <div id="forget-device-container">
- <cr-link-row id="forget-device" class="hr"
- on-click="handleForgetDeviceClick_"
- label="$i18n{multideviceForgetDevice}"
- sub-label="$i18n{multideviceForgetDeviceSummary}"></cr-link-row>
+ <div class="settings-box two-line">
+ <div id="forget-device-label" class="start">
+ $i18n{multideviceForgetDevice}
+ <div class="secondary">
+ $i18n{multideviceForgetDeviceSummary}
+ </div>
+ </div>
+ <cr-button on-click="handleForgetDeviceClick_"
+ aria-labelledby="forgetDeviceLabel">
+ $i18n{multideviceForgetDeviceDisconnect}
+ </cr-button>
</div>
<cr-dialog id="forgetDeviceDialog">
<div slot="title">$i18n{multideviceForgetDevice}</div>
@@ -120,7 +122,7 @@
<cr-button id="confirmButton"
class="action-button"
on-click="onForgetDeviceDialogConfirmClick_">
- $i18n{confirm}
+ $i18n{multideviceForgetDeviceDisconnect}
</cr-button>
</div>
</cr-dialog>
diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html
index 326a4c50e00..4809023c3b1 100644
--- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html
+++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html
@@ -1,6 +1,5 @@
<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.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">
<link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html">
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 fe69ece9bc2..d9ab5429c4c 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
@@ -165,6 +165,6 @@ Polymer({
* @private
*/
getTetherNetworkUrlSearchParams_: function() {
- return new URLSearchParams('type=' + CrOnc.Type.TETHER);
+ return new URLSearchParams('type=Tether');
},
});
diff --git a/chromium/chrome/browser/resources/settings/os_settings_manifest.json b/chromium/chrome/browser/resources/settings/os_settings_manifest.json
index b5aa51b98e5..adbabe2f7bb 100644
--- a/chromium/chrome/browser/resources/settings/os_settings_manifest.json
+++ b/chromium/chrome/browser/resources/settings/os_settings_manifest.json
@@ -1,5 +1,5 @@
{
- "name": "Settings",
+ "name": "$i18nRaw{name}",
"display": "standalone",
"icons": [
{
diff --git a/chromium/chrome/browser/resources/settings/os_settings_resources.grd b/chromium/chrome/browser/resources/settings/os_settings_resources.grd
index 8338d49eb90..9d683c7b298 100644
--- a/chromium/chrome/browser/resources/settings/os_settings_resources.grd
+++ b/chromium/chrome/browser/resources/settings/os_settings_resources.grd
@@ -121,12 +121,6 @@
<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" />
@@ -157,12 +151,6 @@
<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" />
@@ -172,6 +160,18 @@
<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_CAPTIONS_SUBPAGE_JS"
+ file="a11y_page/captions_subpage.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_CAPTIONS_SUBPAGE_HTML"
+ file="a11y_page/captions_subpage.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_FONTS_BROWSER_PROXY_HTML"
+ file="appearance_page/fonts_browser_proxy.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_FONTS_BROWSER_PROXY_JS"
+ file="appearance_page/fonts_browser_proxy.js"
+ type="chrome_html" />
<structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_JS"
file="a11y_page/manage_a11y_page.js"
type="chrome_html" />
@@ -517,12 +517,6 @@
<structure name="IDR_OS_SETTINGS_DEVICE_DISPLAY_OVERSCAN_DIALOG_JS"
file="device_page/display_overscan_dialog.js"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_HTML"
- file="device_page/drive_cache_dialog.html"
- type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_JS"
- file="device_page/drive_cache_dialog.js"
- type="chrome_html" />
<structure name="IDR_OS_SETTINGS_DEVICE_KEYBOARD_HTML"
file="device_page/keyboard.html"
type="chrome_html" />
@@ -775,11 +769,17 @@
<structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_JS"
file="printing_page/cups_printers_entry.js"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_HTML"
- file="printing_page/cups_printers_entry_list.html"
+ <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_HTML"
+ file="printing_page/cups_printers_entry_list_behavior.html"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_JS"
+ file="printing_page/cups_printers_entry_list_behavior.js"
+ type="chrome_html" />
+ <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_HTML"
+ file="printing_page/cups_printers_entry_manager.html"
type="chrome_html" />
- <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_JS"
- file="printing_page/cups_printers_entry_list.js"
+ <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_JS"
+ file="printing_page/cups_printers_entry_manager.js"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_LIST_HTML"
file="printing_page/cups_printers_list.html"
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 3addbf6027c..f5d9d8bc29f 100644
--- a/chromium/chrome/browser/resources/settings/people_page/account_manager.html
+++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.html
@@ -4,6 +4,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/policy/cr_policy_indicator.html">
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/icon.html">
<link rel="import" href="chrome://resources/html/util.html">
@@ -44,8 +45,17 @@
margin-inline-start: 60px;
}
- #account-list-header {
- padding-bottom: 8px;
+ .secondary-accounts-policy-indicator {
+ margin-inline-end: 12px;
+ }
+
+ .settings-box.user-message {
+ align-items: flex-end;
+ }
+
+ #account-list-header > h2 {
+ padding-bottom: 12px;
+ padding-top: 12px;
}
cr-policy-indicator {
@@ -54,7 +64,8 @@
}
#add-account-button {
- margin-top: var(--add-account-margin-top);
+ margin-bottom: 12px;
+ margin-top: 12px;
}
#add-account-icon {
@@ -88,6 +99,11 @@
.management-status {
color: var(--cr-secondary-text-color);
}
+
+ .tooltip-primary-account {
+ margin-inline-end: 12px;
+ margin-inline-start: 12px;
+ }
</style>
<div class="settings-box first">
@@ -99,14 +115,21 @@
</span>
</div>
+ <div id="settings-box-user-message" class="settings-box first user-message"
+ hidden="[[isSecondaryGoogleAccountSigninAllowed_()]]">
+ <cr-policy-pref-indicator class="secondary-accounts-policy-indicator"
+ pref=
+ "[[prefs.account_manager.secondary_google_account_signin_allowed]]">
+ </cr-policy-pref-indicator>
+ <div id="user-message-text" class="secondary">
+ [[getSecondaryAccountsDisabledUserMessage_()]]
+ </div>
+ </div>
+
<div class="settings-box first">
<div id="account-list-header" class="flex">
<h2>$i18n{accountListHeader}</h2>
</div>
- <cr-policy-indicator
- hidden="[[isSecondaryGoogleAccountSigninAllowed_()]]"
- indicator-type="userPolicy">
- </cr-policy-indicator>
<cr-button disabled="[[!isSecondaryGoogleAccountSigninAllowed_()]]"
id="add-account-button" on-tap="addAccount_">
<div id="add-account-icon"></div>
@@ -152,6 +175,11 @@
<!-- If this is the Device Account, display the management status -->
<template is="dom-if" if="[[item.isDeviceAccount]]">
+ <cr-tooltip-icon icon-class="cr:info-outline"
+ class="tooltip-primary-account"
+ tooltip-text="$i18n{accountManagerPrimaryAccountTooltip}"
+ icon-aria-label="$i18n{accountManagerPrimaryAccountTooltip}">
+ </cr-tooltip-icon>
<span class="management-status">
[[getManagementLabel_(item)]]
</span>
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 8613c1262a3..e5cecdcd17f 100644
--- a/chromium/chrome/browser/resources/settings/people_page/account_manager.js
+++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.js
@@ -70,6 +70,17 @@ Polymer({
},
/**
+ * @return {string} 'Secondary Accounts disabled' message depending on
+ * account type
+ * @private
+ */
+ getSecondaryAccountsDisabledUserMessage_: function() {
+ return loadTimeData.getBoolean('isChild')
+ ? this.i18n('accountManagerSecondaryAccountsDisabledChildText')
+ : this.i18n('accountManagerSecondaryAccountsDisabledText');
+ },
+
+ /**
* @param {string} iconUrl
* @return {string} A CSS image-set for multiple scale factors.
* @private
diff --git a/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html b/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html
index ec1fb7827e3..093bace2c14 100644
--- a/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html
+++ b/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html
@@ -13,6 +13,10 @@
<style include="settings-shared">
#pinKeyboardDiv {
justify-content: center;
+ };
+
+ #pinKeyboard {
+ --cr-input-placeholder-letter-spacing: normal;
}
</style>
<cr-dialog id="dialog" on-close="close"
@@ -28,7 +32,8 @@
on-set-pin-done="onSetPinDone_"
set-modes="{{setModes}}"
quick-unlock-private="[[quickUnlockPrivate]]"
- write-uma="[[writeUma_]]">
+ write-uma="[[writeUma_]]"
+ enable-placeholder>
</setup-pin-keyboard>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_page.js b/chromium/chrome/browser/resources/settings/people_page/sync_page.js
index fd28dad676a..e65b7efd44b 100644
--- a/chromium/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.js
@@ -506,7 +506,10 @@ Polymer({
case settings.PageStatus.PASSPHRASE_FAILED:
if (this.pageStatus_ == this.pages_.CONFIGURE && this.syncPrefs &&
this.syncPrefs.passphraseRequired) {
- this.$$('#existingPassphraseInput').invalid = true;
+ const passphraseInput = /** @type {!CrInputElement} */ (
+ this.$$('#existingPassphraseInput'));
+ passphraseInput.invalid = true;
+ passphraseInput.focusInput();
}
return;
}
diff --git a/chromium/chrome/browser/resources/settings/people_page/user_list.html b/chromium/chrome/browser/resources/settings/people_page/user_list.html
index f6ba5eba5bd..dbc871abac2 100644
--- a/chromium/chrome/browser/resources/settings/people_page/user_list.html
+++ b/chromium/chrome/browser/resources/settings/people_page/user_list.html
@@ -47,8 +47,10 @@
<div class="user layout horizontal center two-line">
<img class="user-icon" src="[[getProfilePictureUrl_(item)]]">
<div class="flex layout vertical user-info no-min-width">
- <div class="text-elide">[[getUserName_(item)]]</div>
- <div class="secondary text-elide"
+ <div class="text-elide" title="[[getTooltip_(item)]]">
+ [[getUserName_(item)]]
+ </div>
+ <div class="secondary text-elide" title="[[item.displayEmail]]"
hidden$="[[!shouldShowEmail_(item)]]">
[[item.displayEmail]]
</div>
diff --git a/chromium/chrome/browser/resources/settings/people_page/user_list.js b/chromium/chrome/browser/resources/settings/people_page/user_list.js
index 66786887296..066f71f607c 100644
--- a/chromium/chrome/browser/resources/settings/people_page/user_list.js
+++ b/chromium/chrome/browser/resources/settings/people_page/user_list.js
@@ -123,4 +123,14 @@ Polymer({
shouldShowEmail_: function(user) {
return !user.isSupervised && user.name != user.displayEmail;
},
+
+ /**
+ * Use this function to prevent tooltips from displaying for user names. We
+ * only want to display tooltips for email addresses.
+ * @param {chrome.usersPrivate.User} user
+ * @private
+ */
+ getTooltip_: function(user) {
+ return !this.shouldShowEmail_(user) ? user.displayEmail : '';
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html
index e1caa97fc46..cbcbc0b24d5 100644
--- a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html
+++ b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html
@@ -10,17 +10,17 @@
<dom-module id="settings-users-add-user-dialog">
<template>
<style include="settings-shared">
- cr-input {
- width: var(--settings-input-max-width);
- --cr-input-error-display: none;
+ cr-dialog::part(dialog) {
+ width: 320px;
}
</style>
<cr-dialog id="dialog" close-text="$i18n{close}">
<div slot="title">$i18n{addUsers}</div>
<div slot="body">
<cr-input id="addUserInput" label="$i18n{addUsersEmail}"
- invalid="[[shouldShowError_(isEmail_, isEmpty_)]]"
- on-value-changed="onInput_" autofocus>
+ invalid="[[shouldShowError_(errorCode_)]]"
+ on-value-changed="onInput_"
+ error-message="[[getErrorString_(errorCode_)]]" autofocus>
</cr-input>
</div>
<div slot="button-container">
diff --git a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js
index 3721024821d..a68a908b4b6 100644
--- a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js
+++ b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js
@@ -29,11 +29,26 @@ const EMAIL_REGEX = new RegExp(
'^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)@' +
'([A-Za-z0-9\-]{2,63}\\..+)\\s*$');
+/** @enum {number} */
+const UserAddError = {
+ NO_ERROR: 0,
+ INVALID_EMAIL: 1,
+ USER_EXISTS: 2,
+};
+
Polymer({
is: 'settings-users-add-user-dialog',
+ behaviors: [I18nBehavior],
+
properties: {
/** @private */
+ errorCode_: {
+ type: Number,
+ value: UserAddError.NO_ERROR,
+ },
+
+ /** @private */
isEmail_: {
type: Boolean,
value: false,
@@ -46,6 +61,8 @@ Polymer({
},
},
+ usersPrivate_: chrome.usersPrivate,
+
open: function() {
this.$.addUserInput.value = '';
this.onInput_();
@@ -74,11 +91,20 @@ Polymer({
userEmail = emailMatches[1] + '@' + emailMatches[2];
}
- chrome.usersPrivate.addWhitelistedUser(
- userEmail,
- /* callback */ function(success) {});
- this.$.addUserInput.value = '';
- this.$.dialog.close();
+ this.usersPrivate_.isWhitelistedUser(userEmail, doesUserExist => {
+ if (doesUserExist) {
+ // This user email had been saved previously
+ this.errorCode_ = UserAddError.USER_EXISTS;
+ return;
+ }
+
+ this.$.dialog.close();
+ this.usersPrivate_.addWhitelistedUser(
+ userEmail,
+ /* callback */ function(success) {});
+
+ this.$.addUserInput.value = '';
+ });
},
/**
@@ -99,6 +125,13 @@ Polymer({
const input = this.$.addUserInput.value;
this.isEmail_ = NAME_ONLY_REGEX.test(input) || EMAIL_REGEX.test(input);
this.isEmpty_ = input.length == 0;
+
+ if (!this.isEmail_ && !this.isEmpty_) {
+ this.errorCode_ = UserAddError.INVALID_EMAIL;
+ return;
+ }
+
+ this.errorCode_ = UserAddError.NO_ERROR;
},
/**
@@ -106,7 +139,20 @@ Polymer({
* @return {boolean}
*/
shouldShowError_: function() {
- return !this.isEmail_ && !this.isEmpty_;
+ return this.errorCode_ != UserAddError.NO_ERROR;
+ },
+
+ /**
+ * @private
+ * @return {string}
+ */
+ getErrorString_: function(errorCode_) {
+ if (errorCode_ == UserAddError.USER_EXISTS) {
+ return this.i18n('userExistsError');
+ }
+ //TODO errorString for UserAddError.INVALID_EMAIL crbug/1007481
+
+ return '';
},
});
diff --git a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
index e7619959244..00b021d9f12 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn
@@ -21,7 +21,8 @@ js_type_check("closure_compile") {
":cups_printers",
":cups_printers_browser_proxy",
":cups_printers_entry",
- ":cups_printers_entry_list",
+ ":cups_printers_entry_list_behavior",
+ ":cups_printers_entry_manager",
":cups_printers_list",
":cups_saved_printers",
":printing_browser_proxy",
@@ -82,6 +83,10 @@ if (is_chromeos) {
deps = [
":cups_printer_types",
":cups_printers_browser_proxy",
+ ":cups_printers_entry",
+ ":cups_printers_entry_list_behavior",
+ ":cups_printers_entry_manager",
+ "//ui/webui/resources/js:list_property_update_behavior",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
}
@@ -102,6 +107,7 @@ if (is_chromeos) {
deps = [
":cups_nearby_printers",
":cups_printers_browser_proxy",
+ ":cups_printers_entry_manager",
":cups_saved_printers",
"..:route",
"//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
@@ -128,14 +134,22 @@ if (is_chromeos) {
]
}
- js_library("cups_printers_entry_list") {
+ js_library("cups_printers_entry_list_behavior") {
deps = [
":cups_printer_types",
- ":cups_printers_browser_proxy",
"//ui/webui/resources/js:list_property_update_behavior",
]
}
+ js_library("cups_printers_entry_manager") {
+ deps = [
+ ":cups_printer_types",
+ ":cups_printers_browser_proxy",
+ "//ui/webui/resources/js:assert",
+ "//ui/webui/resources/js:cr",
+ ]
+ }
+
js_library("cups_printers_list") {
deps = [
":cups_printers_browser_proxy",
@@ -149,7 +163,11 @@ if (is_chromeos) {
deps = [
":cups_printer_types",
":cups_printers_browser_proxy",
+ ":cups_printers_entry",
+ ":cups_printers_entry_list_behavior",
+ ":cups_printers_entry_manager",
"//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
+ "//ui/webui/resources/js:list_property_update_behavior",
"//ui/webui/resources/js:web_ui_listener_behavior",
]
}
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 7c9a314bf87..f19b1047748 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
@@ -78,7 +78,8 @@
<template>
<style include="cups-printer-shared"></style>
<add-printer-dialog>
- <div slot="dialog-title">$i18n{addPrintersManuallyTitle}</div>
+ <div slot="dialog-title">
+ $i18n{addPrintersManuallyTitle}
<div id="general-error-container" hidden="[[!errorText_]]">
<div id="general-error">
<iron-icon id="general-error-icon" icon="cr:warning"></iron-icon>
@@ -87,6 +88,7 @@
</div>
</div>
</div>
+ </div>
<div slot="dialog-body">
<div class="settings-box first two-line">
<cr-input class="printer-name-input" autofocus
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 7f78d1dfb77..6b2ceffcc92 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
@@ -445,7 +445,7 @@ Polymer({
.getNetworkStateList({
filter: chromeos.networkConfig.mojom.FilterType.kActive,
networkType: chromeos.networkConfig.mojom.NetworkType.kAll,
- limit: chromeos.networkConfig.mojom.kNoLimit,
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
})
.then((responseParams) => {
this.onActiveNetworksChanged(responseParams.result);
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 7d6bf1824d2..da0573be5ea 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
@@ -1,26 +1,39 @@
<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/html/list_property_update_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
<link rel="import" href="cups_printer_types.html">
<link rel="import" href="cups_printers_browser_proxy.html">
-<link rel="import" href="cups_printers_entry_list.html">
+<link rel="import" href="cups_printers_entry_list_behavior.html">
+<link rel="import" href="cups_printers_entry.html">
+<link rel="import" href="cups_printers_entry_manager.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-cups-nearby-printers">
<template>
- <style include="settings-shared">
- #noPrinterMessage {
- margin-inline-start: 60px;
+ <style include="cups-printer-shared">
+ :host {
+ display: flex;
+ flex-direction: column;
+ }
+
+ #no-search-results {
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}
+
+ <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList"
+ items="[[filteredPrinters_]]">
+ <template>
+ <settings-cups-printers-entry printer-entry="[[item]]">
+ </settings-cups-printers-entry>
+ </template>
+ </iron-list>
+ <div id="no-search-results"
+ hidden="[[!showNoSearchResultsMessage_(searchTerm,
+ filteredPrinters_.*)]]">
+ $i18n{noSearchResults}
</div>
</template>
<script src="cups_nearby_printers.js"></script>
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 aa4912c4010..f4020c2e390 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
@@ -9,20 +9,16 @@
Polymer({
is: 'settings-cups-nearby-printers',
- behaviors: [WebUIListenerBehavior],
+ // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior.
+ behaviors: [
+ CupsPrintersEntryListBehavior,
+ ListPropertyUpdateBehavior,
+ WebUIListenerBehavior,
+ ],
properties: {
/**
- * @type {!Array<!PrinterListEntry>}
- * @private
- */
- nearbyPrinters_: {
- type: Array,
- value: () => [],
- },
-
- /**
- * Search term for filtering |nearbyPrinters_|.
+ * Search term for filtering |nearbyPrinters|.
* @type {string}
*/
searchTerm: {
@@ -30,6 +26,12 @@ Polymer({
value: '',
},
+ /** @type {?CupsPrinterInfo} */
+ activePrinter: {
+ type: Object,
+ notify: true,
+ },
+
/**
* @type {number}
* @private
@@ -39,48 +41,47 @@ Polymer({
value: -1,
},
- /** @type {?CupsPrinterInfo} */
- activePrinter: {
- type: Object,
- notify: true,
+ /**
+ * List of printers filtered through a search term.
+ * @type {!Array<!PrinterListEntry>}
+ * @private
+ */
+ filteredPrinters_: {
+ type: Array,
+ value: () => [],
},
},
listeners: {
'add-automatic-printer': 'onAddAutomaticPrinter_',
+ 'query-discovered-printer': 'onQueryDiscoveredPrinter_',
},
- /** @override */
- attached: function() {
- settings.CupsPrintersBrowserProxyImpl.getInstance()
- .startDiscoveringPrinters();
- this.addWebUIListener(
- 'on-nearby-printers-changed', this.onNearbyPrintersChanged_.bind(this));
- },
+ observers: [
+ 'onSearchOrPrintersChanged_(nearbyPrinters.*, searchTerm)'
+ ],
/**
- * @param {!Array<!CupsPrinterInfo>} automaticPrinters
- * @param {!Array<!CupsPrinterInfo>} discoveredPrinters
+ * Redoes the search whenever |searchTerm| or |nearbyPrinters| changes.
* @private
*/
- onNearbyPrintersChanged_: function(automaticPrinters, discoveredPrinters) {
- if (!automaticPrinters && !discoveredPrinters) {
+ onSearchOrPrintersChanged_: function() {
+ if (!this.nearbyPrinters) {
return;
}
-
- const printers = /** @type{!Array<!PrinterListEntry>} */ ([]);
-
- for (const printer of automaticPrinters) {
- printers.push({printerInfo: printer,
- printerType: PrinterType.AUTOMATIC});
- }
-
- for (const printer of discoveredPrinters) {
- printers.push({printerInfo: printer,
- printerType: PrinterType.DISCOVERED});
- }
-
- this.nearbyPrinters_ = printers;
+ // Filter printers through |searchTerm|. If |searchTerm| is empty,
+ // |filteredPrinters_| is just |nearbyPrinters|.
+ const updatedPrinters = this.searchTerm ?
+ this.nearbyPrinters.filter(
+ item => settings.printing.matchesSearchTerm(
+ item.printerInfo,this.searchTerm)) :
+ this.nearbyPrinters.slice();
+
+ updatedPrinters.sort(settings.printing.sortPrinters);
+
+ this.updateList(
+ 'filteredPrinters_', printer => printer.printerInfo.printerId,
+ updatedPrinters);
},
/**
@@ -100,18 +101,38 @@ Polymer({
},
/**
+ * @param {!CustomEvent<{item: !PrinterListEntry}>} e
+ * @private
+ */
+ onQueryDiscoveredPrinter_: function(e) {
+ const item = e.detail.item;
+ this.setActivePrinter_(item);
+
+ // This is a workaround to ensure type safety on the params of the casted
+ // function. We do this because the closure compiler does not work well with
+ // rejected js promises.
+ const queryDiscoveredPrinterFailed = /** @type {!Function}) */(
+ this.onQueryDiscoveredPrinterFailed_.bind(this));
+ settings.CupsPrintersBrowserProxyImpl.getInstance()
+ .addDiscoveredPrinter(item.printerInfo.printerId)
+ .then(
+ this.onQueryDiscoveredPrinterSucceeded_.bind(this,
+ item.printerInfo.printerName),
+ queryDiscoveredPrinterFailed);
+ },
+
+ /**
* Retrieves the index of |item| in |nearbyPrinters_| and sets that printer as
* the active printer.
* @param {!PrinterListEntry} item
* @private
*/
setActivePrinter_: function(item) {
- this.activePrinterListEntryIndex_ =
- this.nearbyPrinters_.findIndex(
- printer => printer.printerInfo == item.printerInfo);
+ this.activePrinterListEntryIndex_ = this.nearbyPrinters.findIndex(
+ printer => printer.printerInfo.printerId == item.printerInfo.printerId);
this.activePrinter =
- this.get(['nearbyPrinters_', this.activePrinterListEntryIndex_])
+ this.get(['nearbyPrinters', this.activePrinterListEntryIndex_])
.printerInfo;
},
@@ -140,10 +161,32 @@ Polymer({
},
/**
- * @return {boolean} Returns true if noPrinterMessage should be visible.
+ * Handler for queryDiscoveredPrinter success.
+ * @param {string} printerName
+ * @param {!PrinterSetupResult} result
+ * @private
+ */
+ onQueryDiscoveredPrinterSucceeded_: function(printerName, result) {
+ this.fire(
+ 'show-cups-printer-toast',
+ {resultCode: result, printerName: printerName});
+ },
+
+ /**
+ * Handler for queryDiscoveredPrinter failure.
+ * @param {!CupsPrinterInfo} printer
+ * @private
+ */
+ onQueryDiscoveredPrinterFailed_: function(printer) {
+ this.fire('open-manufacturer-model-dialog-for-specified-printer',
+ {item: /** @type {CupsPrinterInfo} */(printer)});
+ },
+
+ /**
+ * @return {boolean} Returns true if the no search message should be visible.
* @private
*/
- shouldShowNoNearbyPrinterMessage_: function() {
- return !this.searchTerm && !this.nearbyPrinters_.length;
+ showNoSearchResultsMessage_: function() {
+ return !!this.searchTerm && !this.filteredPrinters_.length;
}
}); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js
index 15542cb8d1c..46b1be62226 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js
@@ -141,6 +141,40 @@ cr.define('settings.printing', function() {
}
}
+ /**
+ * We sort by printer type, which is based off of a maintained list in
+ * cups_printers_types.js. If the types are the same, we sort alphabetically.
+ * @param {!PrinterListEntry} first
+ * @param {!PrinterListEntry} second
+ * @return {number}
+ */
+ function sortPrinters(first, second) {
+ if (first.printerType == second.printerType) {
+ return settings.printing.alphabeticalSort(
+ first.printerInfo, second.printerInfo);
+ }
+
+ return first.printerType - second.printerType;
+ }
+
+ /**
+ * @param {!CupsPrinterInfo} printer
+ * @param {string} searchTerm
+ * @return {boolean} True if the printer has |searchTerm| in its name.
+ */
+ function matchesSearchTerm(printer, searchTerm) {
+ return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase());
+ }
+
+ /**
+ * @param {!PrinterListEntry} first
+ * @param {!PrinterListEntry} second
+ * @return {boolean}
+ */
+ function arePrinterIdsEqual(first, second) {
+ return first.printerInfo.printerId == second.printerInfo.printerId;
+ }
+
return {
isNetworkProtocol: isNetworkProtocol,
isNameAndAddressValid: isNameAndAddressValid,
@@ -148,5 +182,8 @@ cr.define('settings.printing', function() {
getBaseName: getBaseName,
alphabeticalSort: alphabeticalSort,
getErrorText: getErrorText,
+ sortPrinters: sortPrinters,
+ matchesSearchTerm: matchesSearchTerm,
+ arePrinterIdsEqual: arePrinterIdsEqual,
};
});
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
index cda0410aaa6..68ee364dca0 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html
@@ -68,6 +68,10 @@
width: 100%;
}
+ .flex-auto {
+ flex: 1 1 auto;
+ }
+
.list-item {
background: none;
border: none;
@@ -109,6 +113,10 @@
font-size: 10px;
margin-inline-start: 5px;
}
+
+ #no-search-results {
+ text-align: center;
+ }
</style>
</template>
</dom-module>
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 6777282b161..c5b866a04bc 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -16,6 +16,7 @@
<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_entry_manager.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">
@@ -142,7 +143,6 @@
<settings-cups-saved-printers id="savedPrinters"
active-printer="{{activePrinter}}"
- saved-printers="[[savedPrinters_]]"
search-term="[[searchTerm]]">
</settings-cups-saved-printers>
</div>
@@ -197,7 +197,7 @@
</settings-cups-edit-printer-dialog>
</template>
- <cr-toast id="errorToast" duration="3000">
+ <cr-toast id="errorToast" duration="3000" role="alert">
<div class="error-message" id="addPrinterDoneMessage">
[[addPrinterResultText_]]
</div>
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 21109350ab6..ece618460ad 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js
@@ -81,11 +81,16 @@ Polymer({
/** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
networkConfig_: null,
+ /** @private {settings.printing.CupsPrintersEntryManager} */
+ entryManager_: null,
+
/** @override */
created: function() {
this.networkConfig_ =
network_config.MojoInterfaceProviderImpl.getInstance()
.getMojoServiceRemote();
+ this.entryManager_ =
+ settings.printing.CupsPrintersEntryManager.getInstance();
},
/** @override */
@@ -94,7 +99,7 @@ Polymer({
.getNetworkStateList({
filter: chromeos.networkConfig.mojom.FilterType.kActive,
networkType: chromeos.networkConfig.mojom.NetworkType.kAll,
- limit: chromeos.networkConfig.mojom.kNoLimit,
+ limit: chromeos.networkConfig.mojom.NO_LIMIT,
})
.then((responseParams) => {
this.onActiveNetworksChanged(responseParams.result);
@@ -110,7 +115,6 @@ Polymer({
this.updateCupsPrintersList_();
},
-
/**
* settings.RouteObserverBehavior
* @param {!settings.Route} route
@@ -119,10 +123,14 @@ Polymer({
currentRouteChanged: function(route) {
if (route != settings.routes.CUPS_PRINTERS) {
cr.removeWebUIListener('on-printers-changed');
+ this.entryManager_.removeWebUIListeners();
return;
}
+
+ this.entryManager_.addWebUIListeners();
cr.addWebUIListener(
'on-printers-changed', this.onPrintersChanged_.bind(this));
+ this.updateCupsPrintersList_();
},
/**
@@ -148,17 +156,15 @@ Polymer({
* }>} event
* @private
*/
- openResultToast_: function(event) {
+ openResultToast_: function(event) {
const printerName = event.detail.printerName;
switch (event.detail.resultCode) {
case PrinterSetupResult.SUCCESS:
- this.updateCupsPrintersList_();
this.addPrinterResultText_ =
loadTimeData.getStringF('printerAddedSuccessfulMessage',
printerName);
break;
case PrinterSetupResult.EDIT_SUCCESS:
- this.updateCupsPrintersList_();
this.addPrinterResultText_ =
loadTimeData.getStringF('printerEditedSuccessfulMessage',
printerName);
@@ -203,6 +209,7 @@ Polymer({
printer => /** @type {!PrinterListEntry} */({
printerInfo: printer,
printerType: PrinterType.SAVED}));
+ this.entryManager_.setSavedPrintersList(this.savedPrinters_);
} else {
this.printers = cupsPrintersList.printerList;
}
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 c8df839a0ee..8d7c6b5145c 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
@@ -29,7 +29,7 @@
<template is="dom-if"
if="[[isDiscoveredPrinter_(printerEntry.printerType)]]">
<cr-button id="setupPrinterButton"
- on-click="onOpenManufacturerModelDialogTap_">
+ on-click="onAddDiscoveredPrinterTap_">
$i18n{setupPrinter}
</cr-button>
</template>
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js
index fe225dcf9fa..5734b7717ae 100644
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js
@@ -33,9 +33,8 @@ Polymer({
});
},
- onOpenManufacturerModelDialogTap_: function(e) {
- this.fire('open-manufacturer-model-dialog-for-specified-printer',
- {item: this.printerEntry.printerInfo});
+ onAddDiscoveredPrinterTap_: function(e) {
+ this.fire('query-discovered-printer', {item: this.printerEntry});
},
onAddAutomaticPrinterTap_: function() {
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
deleted file mode 100644
index bf9fbaf1f9f..00000000000
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/html/list_property_update_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
-<link rel="import" href="cups_printer_dialog_util.html">
-<link rel="import" href="cups_printer_types.html">
-<link rel="import" href="cups_printers_browser_proxy.html">
-<link rel="import" href="cups_printers_entry.html">
-<link rel="import" href="../settings_shared_css.html">
-
-<dom-module id="settings-cups-printers-entry-list">
- <template>
- <style include="settings-shared">
- :host {
- display: flex;
- flex-direction: column;
- }
-
- 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_]]">
- <template>
- <settings-cups-printers-entry printer-entry="[[item]]">
- </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
deleted file mode 100644
index 3fe5f69bd12..00000000000
--- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js
+++ /dev/null
@@ -1,110 +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 'settings-cups-printers-entry-list' is a component for a list
- * of PrinterListEntry's.
- */
-Polymer({
- is: 'settings-cups-printers-entry-list',
-
- behaviors: [
- ListPropertyUpdateBehavior,
- ],
-
- properties: {
- /**
- * List of printers.
- * @type {!Array<!PrinterListEntry>}
- */
- printers: {
- type: Array,
- value: () => [],
- },
-
- /**
- * List of printers filtered through a search term.
- * @type {!Array<!PrinterListEntry>}
- * @private
- */
- filteredPrinters_: {
- type: Array,
- value: () => [],
- },
-
- /**
- * Search term for filtering |printers|.
- * @type {string}
- */
- searchTerm: {
- type: String,
- value: '',
- },
-
- /**
- * Whether to show the no search results message.
- * @type {boolean}
- * @private
- */
- showNoSearchResultsMessage_: {
- type: Boolean,
- value: false,
- },
- },
-
- observers: [
- 'onSearchChanged_(printers.*, searchTerm)'
- ],
-
- /**
- * Redoes the search whenever |searchTerm| or |printers| changes.
- * @private
- */
- onSearchChanged_: function() {
- if (!this.printers) {
- return;
- }
- // Filter printers through |searchTerm|. If |searchTerm| is empty,
- // |filteredPrinters_| is just |printers|.
- const updatedPrinters = this.searchTerm ?
- this.printers.filter(
- item =>this.matchesSearchTerm_(item.printerInfo,this.searchTerm)) :
- this.printers.slice();
-
- 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;
- },
-
- /**
- * @param {!CupsPrinterInfo} printer
- * @param {string} searchTerm
- * @return {boolean} True if the printer has |searchTerm| in its name.
- * @private
- */
- matchesSearchTerm_: function(printer, searchTerm) {
- return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase());
- }
-});
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html
new file mode 100644
index 00000000000..6f30319498f
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html
@@ -0,0 +1,2 @@
+<link rel="import" href="cups_printer_types.html">
+<script src="cups_printers_entry_list_behavior.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js
new file mode 100644
index 00000000000..59588b24629
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js
@@ -0,0 +1,98 @@
+// 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 Polymer behavior for observing CupsPrintersEntryManager events.
+ * Use this behavior if you want to receive a dynamically updated list of both
+ * saved and nearby printers.
+ */
+
+/** @polymerBehavior */
+const CupsPrintersEntryListBehavior = {
+ properties: {
+ /** @private {!settings.printing.CupsPrintersEntryManager} */
+ entryManager_: Object,
+
+ /** @type {!Array<!PrinterListEntry>} */
+ savedPrinters: {
+ type: Array,
+ value: () => [],
+ },
+
+ /** @type {!Array<!PrinterListEntry>} */
+ nearbyPrinters: {
+ type: Array,
+ value: () => [],
+ },
+ },
+
+ /** @override */
+ created: function() {
+ this.entryManager_ =
+ settings.printing.CupsPrintersEntryManager.getInstance();
+ },
+
+ /** @override */
+ attached: function() {
+ this.entryManager_.addOnSavedPrintersChangedListener(
+ this.onSavedPrintersChanged_.bind(this));
+ this.entryManager_.addOnNearbyPrintersChangedListener(
+ this.onNearbyPrintersChanged_.bind(this));
+
+ // Initialize saved and nearby printers list.
+ this.onSavedPrintersChanged_(
+ this.entryManager_.savedPrinters, [] /* printerAdded */,
+ [] /* printerRemoved */);
+ this.onNearbyPrintersChanged_(this.entryManager_.nearbyPrinters);
+ },
+
+ /** @override */
+ detached: function() {
+ this.entryManager_.removeOnSavedPrintersChangedListener(
+ this.onSavedPrintersChanged_.bind(this));
+ this.entryManager_.removeOnNearbyPrintersChangedListener(
+ this.onNearbyPrintersChanged_.bind(this));
+ },
+
+ /**
+ * Non-empty params indicate the applicable change to be notified.
+ * @param {!Array<!PrinterListEntry>} savedPrinters
+ * @param {!Array<!PrinterListEntry>} addedPrinters
+ * @param {!Array<!PrinterListEntry>} removedPrinters
+ * @private
+ */
+ onSavedPrintersChanged_: function(
+ savedPrinters, addedPrinters, removedPrinters) {
+ this.updateList(
+ 'savedPrinters', printer => printer.printerInfo.printerId,
+ savedPrinters);
+
+ assert(!(addedPrinters.length && removedPrinters.length));
+
+ if (addedPrinters.length) {
+ this.onSavedPrintersAdded(addedPrinters);
+ } else if (removedPrinters.length) {
+ this.onSavedPrintersRemoved(removedPrinters);
+ }
+ },
+
+ /**
+ * @param {!Array<!PrinterListEntry>} printerList
+ * @private
+ */
+ onNearbyPrintersChanged_: function(printerList) {
+ this.updateList(
+ 'nearbyPrinters', printer => printer.printerInfo.printerId,
+ printerList);
+ },
+
+ // CupsPrintersEntryListBehavior methods. Override these in the
+ // implementations.
+
+ /** @param{!Array<!PrinterListEntry>} addedPrinters */
+ onSavedPrintersAdded: function(addedPrinters) {},
+
+ /** @param{!Array<!PrinterListEntry>} removedPrinters */
+ onSavedPrintersRemoved: function(removedPrinters) {},
+}; \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html
new file mode 100644
index 00000000000..d8e4aac3867
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html
@@ -0,0 +1,5 @@
+<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="chrome://resources/html/cr.html">
+<link rel="import" href="cups_printer_types.html">
+<link rel="import" href="cups_printers_browser_proxy.html">
+<script src="cups_printers_entry_manager.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js
new file mode 100644
index 00000000000..86908fbb3c3
--- /dev/null
+++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js
@@ -0,0 +1,182 @@
+// 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 which provides the client with metadata about a change
+ * to a list of saved printers. The first parameter is the updated list of
+ * printers after the change, the second parameter is the newly-added printer
+ * (if it exists), and the third parameter is the newly-removed printer
+ * (if it exists).
+ * @typedef {!function(!Array<!PrinterListEntry>, !Array<!PrinterListEntry>,
+ * !Array<!PrinterListEntry>): void}
+ */
+let PrintersListWithDeltasCallback;
+
+/**
+ * Function which provides the client with a list that contains the nearby
+ * printers list. The parameter is the updated list of printers after any
+ * changes.
+ * @typedef {function(!Array<!PrinterListEntry>): void}
+ */
+let PrintersListCallback;
+
+cr.define('settings.printing', function() {
+ /**
+ * Finds the printers that are in |firstArr| but not in |secondArr|.
+ * @param {!Array<!PrinterListEntry>} firstArr
+ * @param {!Array<!PrinterListEntry>} secondArr
+ * @return {!Array<!PrinterListEntry>}
+ * @private
+ */
+ function findDifference_(firstArr, secondArr) {
+ return firstArr.filter((firstArrEntry) => {
+ return !secondArr.some(
+ p => p.printerInfo.printerId == firstArrEntry.printerInfo.printerId);
+ });
+ }
+
+ /**
+ * Class for managing printer entries. Holds both Saved and Nearby printers
+ * and notifies observers of any applicable changes to either printer lists.
+ */
+ class CupsPrintersEntryManager {
+ constructor() {
+ /** @private {!Array<!PrinterListEntry>} */
+ this.savedPrinters_ = [];
+
+ /** @private {!Array<!PrinterListEntry>} */
+ this.nearbyPrinters_ = [];
+
+ /** @private {!Array<PrintersListWithDeltasCallback>} */
+ this.onSavedPrintersChangedListeners_ = [];
+
+ /** @type {!Array<PrintersListCallback>} */
+ this.onNearbyPrintersChangedListeners_ = [];
+ }
+
+ addWebUIListeners() {
+ // TODO(1005905): Add on-printers-changed listener here once legacy code
+ // is removed.
+ cr.addWebUIListener(
+ 'on-nearby-printers-changed', this.setNearbyPrintersList.bind(this));
+ settings.CupsPrintersBrowserProxyImpl.getInstance()
+ .startDiscoveringPrinters();
+ }
+
+ removeWebUIListeners() {
+ cr.removeWebUIListener('on-nearby-printers-changed');
+ }
+
+ /** @return {!Array<!PrinterListEntry>} */
+ get savedPrinters() {
+ return this.savedPrinters_;
+ }
+
+ /** @return {!Array<!PrinterListEntry>} */
+ get nearbyPrinters() {
+ return this.nearbyPrinters_;
+ }
+
+ /** @param {PrintersListWithDeltasCallback} listener */
+ addOnSavedPrintersChangedListener(listener) {
+ this.onSavedPrintersChangedListeners_.push(listener);
+ }
+
+ /** @param {PrintersListWithDeltasCallback} listener */
+ removeOnSavedPrintersChangedListener(listener) {
+ this.onSavedPrintersChangedListeners_ =
+ this.onSavedPrintersChangedListeners_.filter(lis => lis != listener);
+ }
+
+ /** @param {PrintersListCallback} listener */
+ addOnNearbyPrintersChangedListener(listener) {
+ this.onNearbyPrintersChangedListeners_.push(listener);
+ }
+
+ /** @param {PrintersListCallback} listener */
+ removeOnNearbyPrintersChangedListener(listener) {
+ this.onNearbyPrintersChangedListeners_ =
+ this.onNearbyPrintersChangedListeners_.filter(lis => lis != listener);
+ }
+
+ /**
+ * Sets the saved printers list and notifies observers of any applicable
+ * changes.
+ * @param {!Array<!PrinterListEntry>} printerList
+ */
+ setSavedPrintersList(printerList) {
+ if (printerList.length > this.savedPrinters_.length) {
+ const diff = findDifference_(printerList, this.savedPrinters_);
+ this.savedPrinters_ = printerList;
+ this.notifyOnSavedPrintersChangedListeners_(
+ this.savedPrinters_, diff, [] /* printersRemoved */);
+ return;
+ }
+
+ if (printerList.length < this.savedPrinters_.length) {
+ const diff = findDifference_(this.savedPrinters_, printerList);
+ this.savedPrinters_ = printerList;
+ this.notifyOnSavedPrintersChangedListeners_(
+ this.savedPrinters_, [] /* printersAdded */, diff);
+ return;
+ }
+
+ this.savedPrinters_ = printerList;
+ this.notifyOnSavedPrintersChangedListeners_(
+ this.savedPrinters_, [] /* printersAdded */,
+ [] /* printersRemoved */);
+ }
+
+ /**
+ * Sets the nearby printers list and notifies observers of any applicable
+ * changes.
+ * @param {!Array<!CupsPrinterInfo>} automaticPrinters
+ * @param {!Array<!CupsPrinterInfo>} discoveredPrinters
+ */
+ setNearbyPrintersList(automaticPrinters, discoveredPrinters) {
+ if (!automaticPrinters && !discoveredPrinters) {
+ return;
+ }
+
+ this.nearbyPrinters_ = [];
+
+ for (const printer of automaticPrinters) {
+ this.nearbyPrinters_.push(
+ {printerInfo: printer, printerType: PrinterType.AUTOMATIC});
+ }
+
+ for (const printer of discoveredPrinters) {
+ this.nearbyPrinters_.push(
+ {printerInfo: printer, printerType: PrinterType.DISCOVERED});
+ }
+
+ this.notifyOnNearbyPrintersChangedListeners_();
+ }
+
+ /**
+ * Non-empty/null fields indicate the applicable change to be notified.
+ * @param {!Array<!PrinterListEntry>} savedPrinters
+ * @param {!Array<!PrinterListEntry>} addedPrinter
+ * @param {!Array<!PrinterListEntry>} removedPrinter
+ * @private
+ */
+ notifyOnSavedPrintersChangedListeners_(
+ savedPrinters, addedPrinter, removedPrinter) {
+ this.onSavedPrintersChangedListeners_.forEach(
+ listener => listener(savedPrinters, addedPrinter, removedPrinter));
+ }
+
+ /** @private */
+ notifyOnNearbyPrintersChangedListeners_() {
+ this.onNearbyPrintersChangedListeners_.forEach(
+ listener => listener(this.nearbyPrinters_));
+ }
+ }
+
+ cr.addSingletonGetter(CupsPrintersEntryManager);
+
+ return {
+ CupsPrintersEntryManager: CupsPrintersEntryManager,
+ };
+}); \ No newline at end of file
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 1bb09c08fc0..c89d0230a99 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
@@ -1,14 +1,52 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
+<link rel="import" href="chrome://resources/html/list_property_update_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_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-list/iron-list.html">
<link rel="import" href="cups_printer_types.html">
<link rel="import" href="cups_printers_browser_proxy.html">
-<link rel="import" href="cups_printers_entry_list.html">
+<link rel="import" href="cups_printers_entry_list_behavior.html">
+<link rel="import" href="cups_printers_entry.html">
<link rel="import" href="../settings_shared_css.html">
<dom-module id="settings-cups-saved-printers">
<template>
+ <style include="cups-printer-shared iron-flex iron-flex-alignment
+ iron-flex-factors">
+ :host {
+ display: flex;
+ flex-direction: column;
+ }
+
+ #no-search-results {
+ margin-bottom: 20px;
+ }
+
+ /** Height of iron list row entry. */
+ #show-more-container {
+ min-height: var(--settings-row-min-height);
+ }
+
+ /** Border line that is the same size as a list entry's border. */
+ #show-more-line-separator {
+ border-bottom: var(--cr-separator-line);
+ left: 60px;
+ position: relative;
+ right: 20px;
+ width: 596px;
+ }
+
+ #show-more-icon {
+ --cr-icon-button-margin-end: 0;
+ }
+
+ #show-more-text {
+ flex: 1;
+ }
+ </style>
+
<cr-action-menu>
<button id="editButton" class="dropdown-item" on-click="onEditTap_">
$i18n{editPrinter}
@@ -18,10 +56,32 @@
</button>
</cr-action-menu>
- <style include="settings-shared"></style>
- <settings-cups-printers-entry-list printers="[[savedPrinters]]"
- search-term="[[searchTerm]]">
- </settings-cups-printers-entry-list>
+ <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList"
+ items="[[filteredPrinters_]]">
+ <template>
+ <settings-cups-printers-entry printer-entry="[[item]]">
+ </settings-cups-printers-entry>
+ </template>
+ </iron-list>
+ <template is="dom-if" id="show-more-button-section"
+ if="[[shouldPrinterListBeCollapsed_(searchTerm, savedPrinters.*,
+ newPrinters_.*, hasShowMoreBeenTapped_)]]" restamp>
+ <div id="show-more-line-separator"></div>
+ <div class="list-frame layout horizontal" id="show-more-container">
+ <div id="show-more-text">$i18n{showMorePrinters}</div>
+ <cr-icon-button class="action-button" id="show-more-icon"
+ iron-icon="cr:expand-more"
+ on-click="onShowMoreTap_"
+ title=$i18n{showMorePrinters}>
+ </cr-icon-button>
+ </div>
+ </template>
+
+ <div id="no-search-results"
+ hidden="[[!showNoSearchResultsMessage_(searchTerm,
+ filteredPrinters_.*)]]">
+ $i18n{noSearchResults}
+ </div>
</template>
<script src="cups_saved_printers.js"></script>
</dom-module>
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 85ef694f1ec..948bc0526ab 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
@@ -2,6 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+(function() {
+
+// If the Show more button is visible, the minimum number of printers we show
+// is 3.
+const kMinVisiblePrinters = 3;
+
+/**
+ * Move a printer's position in |printerArr| from |fromIndex| to |toIndex|.
+ * @param {!Array<!PrinterListEntry>} printerArr
+ * @param {number} fromIndex
+ * @param {number} toIndex
+ */
+function moveEntryInPrinters(printerArr, fromIndex, toIndex) {
+ const element = printerArr[fromIndex];
+ printerArr.splice(fromIndex, 1);
+ printerArr.splice(toIndex, 0, element);
+}
+
/**
* @fileoverview 'settings-cups-saved-printers' is a list container for Saved
* Printers.
@@ -9,16 +27,14 @@
Polymer({
is: 'settings-cups-saved-printers',
+ // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior.
behaviors: [
- WebUIListenerBehavior,
+ CupsPrintersEntryListBehavior,
+ ListPropertyUpdateBehavior,
+ WebUIListenerBehavior,
],
properties: {
- /** @type {!Array<!PrinterListEntry>} */
- savedPrinters: {
- type: Array,
- },
-
/**
* Search term for filtering |savedPrinters|.
* @type {string}
@@ -28,6 +44,12 @@ Polymer({
value: '',
},
+ /** @type {?CupsPrinterInfo} */
+ activePrinter: {
+ type: Object,
+ notify: true,
+ },
+
/**
* @type {number}
* @private
@@ -37,10 +59,36 @@ Polymer({
value: -1,
},
- /** @type {?CupsPrinterInfo} */
- activePrinter: {
- type: Object,
- notify: true,
+ /**
+ * List of printers filtered through a search term.
+ * @type {!Array<!PrinterListEntry>}
+ * @private
+ */
+ filteredPrinters_: {
+ type: Array,
+ value: () => [],
+ },
+
+ /**
+ * Array of new PrinterListEntry's that were added during this session.
+ * @type {!Array<!PrinterListEntry>}
+ * @private
+ */
+ newPrinters_: {
+ type: Array,
+ value: () => [],
+ },
+
+ /**
+ * Keeps track of whether the user has tapped the Show more button. A search
+ * term will expand the collapsed list, so we need to keep track of whether
+ * the list expanded because of a search term or because the user tapped on
+ * the Show more button.
+ * @private
+ */
+ hasShowMoreBeenTapped_: {
+ type: Boolean,
+ value: false,
},
},
@@ -48,23 +96,50 @@ Polymer({
'open-action-menu': 'onOpenActionMenu_',
},
+ observers: [
+ 'onSearchOrPrintersChanged_(savedPrinters.*, searchTerm,' +
+ 'hasShowMoreBeenTapped_, newPrinters_.*)'
+ ],
+
/** @private {settings.CupsPrintersBrowserProxy} */
browserProxy_: null,
+ /**
+ * The number of printers we display if hidden printers are allowed.
+ * kMinVisiblePrinters is the default value and we never show fewer printers
+ * if the Show more button is visible.
+ */
+ visiblePrinterCounter_: kMinVisiblePrinters,
+
/** @override */
created: function() {
this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance();
},
/**
+ * Redoes the search whenever |searchTerm| or |savedPrinters| changes.
+ * @private
+ */
+ onSearchOrPrintersChanged_: function() {
+ if (!this.savedPrinters) {
+ return;
+ }
+
+ const updatedPrinters = this.getVisiblePrinters_();
+
+ this.updateList(
+ 'filteredPrinters_', printer => printer.printerInfo.printerId,
+ updatedPrinters);
+ },
+
+ /**
* @param {!CustomEvent<{target: !HTMLElement, item: !PrinterListEntry}>} e
* @private
*/
onOpenActionMenu_: function(e) {
const item = /** @type {!PrinterListEntry} */(e.detail.item);
- this.activePrinterListEntryIndex_ =
- this.savedPrinters.findIndex(
- printer => printer.printerInfo == item.printerInfo);
+ this.activePrinterListEntryIndex_ = this.savedPrinters.findIndex(
+ printer => printer.printerInfo.printerId == item.printerInfo.printerId);
this.activePrinter =
this.get(['savedPrinters', this.activePrinterListEntryIndex_])
.printerInfo;
@@ -90,7 +165,131 @@ Polymer({
},
/** @private */
+ onShowMoreTap_: function() {
+ this.hasShowMoreBeenTapped_ = true;
+ },
+
+ /**
+ * Gets the printers to be shown in the UI. These printers are filtered
+ * by the search term, alphabetically sorted (if applicable), and are the
+ * printers not hidden by the Show more section.
+ * @return {!Array<!PrinterListEntry>} Returns only the visible printers.
+ * @private
+ */
+ getVisiblePrinters_: function() {
+ // Filter printers through |searchTerm|. If |searchTerm| is empty,
+ // |filteredPrinters_| is just |savedPrinters|.
+ const updatedPrinters = this.searchTerm ?
+ this.savedPrinters.filter(
+ item => settings.printing.matchesSearchTerm(
+ item.printerInfo, this.searchTerm)) :
+ this.savedPrinters.slice();
+
+ updatedPrinters.sort(settings.printing.sortPrinters);
+
+ this.moveNewlyAddedPrinters_(updatedPrinters, 0 /* toIndex */);
+
+ if (this.shouldPrinterListBeCollapsed_()) {
+ // If the Show more button is visible, we only display the first
+ // N < |visiblePrinterCounter_| printers and the rest are hidden.
+ return updatedPrinters.filter(
+ (printer, idx) => idx < this.visiblePrinterCounter_);
+ }
+ return updatedPrinters;
+ },
+
+ /** @private */
closeActionMenu_: function() {
this.$$('cr-action-menu').close();
+ },
+
+ /**
+ * @return {boolean} Returns true if the no search message should be visible.
+ * @private
+ */
+ showNoSearchResultsMessage_: function() {
+ return !!this.searchTerm && !this.filteredPrinters_.length;
+ },
+
+ /** @param{!Array<!PrinterListEntry>} addedPrinters */
+ onSavedPrintersAdded: function(addedPrinters) {
+ const currArr = this.newPrinters_.slice();
+ for (const printer of addedPrinters) {
+ this.visiblePrinterCounter_++;
+ currArr.push(printer);
+ }
+
+ this.set('newPrinters_', currArr);
+ },
+
+ /** @param{!Array<!PrinterListEntry>} removedPrinters */
+ onSavedPrintersRemoved: function(removedPrinters) {
+ const currArr = this.newPrinters_.slice();
+ for (const printer of removedPrinters) {
+ const newPrinterRemovedIdx = currArr.findIndex(
+ p => p.printerInfo.printerId == printer.printerInfo.printerId);
+ // If the removed printer is a recently added printer, remove it from
+ // |currArr|.
+ if (newPrinterRemovedIdx > -1) {
+ currArr.splice(newPrinterRemovedIdx, 1);
+ }
+
+ this.visiblePrinterCounter_ = Math.max(
+ kMinVisiblePrinters, --this.visiblePrinterCounter_);
+ }
+
+ this.set('newPrinters_', currArr);
+ },
+
+ /**
+ * Keeps track of whether the Show more button should be visible which means
+ * that the printer list is collapsed. There are two ways a collapsed list
+ * may be expanded: the Show more button is tapped or if there is a search
+ * term.
+ * @return {boolean} True if the printer list should be collapsed.
+ * @private
+ */
+ shouldPrinterListBeCollapsed_: function() {
+ // If |searchTerm| is set, never collapse the list.
+ if (this.searchTerm) {
+ return false;
+ }
+
+ // If |hasShowMoreBeenTapped_| is set to true, never collapse the list.
+ if (this.hasShowMoreBeenTapped_) {
+ return false;
+ }
+
+ // If the total number of saved printers does not exceed the number of
+ // visible printers, there is no need for the list to be collapsed.
+ if (this.savedPrinters.length - this.visiblePrinterCounter_ < 1) {
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * Moves printers that are in |newPrinters_| to position |toIndex| of
+ * |printerArr|. This moves all recently added printers to the top of the
+ * printer list.
+ * @param {!Array<!PrinterListEntry>} printerArr
+ * @param {number} toIndex
+ * @private
+ */
+ moveNewlyAddedPrinters_: function(printerArr, toIndex) {
+ if (!this.newPrinters_.length) {
+ return;
+ }
+
+ // We have newly added printers, move them to the top of the list.
+ for (const printer of this.newPrinters_) {
+ const idx = printerArr.findIndex(
+ p => p.printerInfo.printerId == printer.printerInfo.printerId);
+ if (idx > -1) {
+ moveEntryInPrinters(printerArr, idx, toIndex);
+ }
+ }
}
});
+})();
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html
index 491eff1b6aa..34d663a378f 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -2,10 +2,12 @@
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="../controls/settings_toggle_button.html">
<link rel="import" href="../lifetime_browser_proxy.html">
<link rel="import" href="../people_page/sync_browser_proxy.html">
+<link rel="import" href="../prefs/prefs.html">
<link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../route.html">
<link rel="import" href="../settings_shared_css.html">
@@ -43,10 +45,23 @@
label="$i18n{safeBrowsingEnableProtection}"
sub-label="$i18n{safeBrowsingEnableProtectionDesc}">
</settings-toggle-button>
+ <settings-toggle-button id="passwordsLeakDetectionCheckbox"
+ pref="{{prefs.profile.password_manager_leak_detection}}"
+ checked="[[getCheckedLeakDetection_(
+ userSignedIn_, passwordsLeakDetectionAvailable_)]]"
+ label="$i18n{passwordsLeakDetectionLabel}"
+ sub-label="[[getPasswordsLeakDetectionSubLabel_(
+ userSignedIn_, passwordsLeakDetectionAvailable_)]]"
+ hidden$="[[!passwordsLeakDetectionEnabled_]]"
+ disabled="[[getDisabledLeakDetection_(
+ userSignedIn_, prefs.*)]]">
+ </settings-toggle-button>
<settings-toggle-button
pref="{{prefs.safebrowsing.scout_reporting_enabled}}"
+ checked="[[getCheckedExtendedSafeBrowsing_(prefs.*)]]"
label="$i18n{safeBrowsingEnableExtendedReporting}"
- sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}">
+ sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"
+ disabled="[[getDisabledExtendedSafeBrowsing_(prefs.*)]]">
</settings-toggle-button>
<if expr="_google_chrome">
<if expr="chromeos">
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js
index f3a7ad0b10b..5d066a1dee6 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js
@@ -13,6 +13,7 @@ Polymer({
is: 'settings-personalization-options',
behaviors: [
+ I18nBehavior,
PrefsBehavior,
WebUIListenerBehavior,
],
@@ -34,6 +35,29 @@ Polymer({
/** @type {settings.SyncStatus} */
syncStatus: Object,
+ // <if expr="not chromeos">
+ /** @private {Array<!settings.StoredAccount>} */
+ storedAccounts_: Object,
+ // </if>
+
+ /** @private */
+ userSignedIn_: {
+ type: Boolean,
+ computed: 'computeUserSignedIn_(syncStatus, storedAccounts_)',
+ },
+
+ /** @private */
+ passwordsLeakDetectionAvailable_: {
+ type: Boolean,
+ computed: 'computePasswordsLeakDetectionAvailable_(prefs.*)',
+ },
+
+ /** @private */
+ passwordsLeakDetectionEnabled_: {
+ type: Boolean,
+ value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'),
+ },
+
// <if expr="_google_chrome and not chromeos">
// TODO(dbeam): make a virtual.* pref namespace and set/get this normally
// (but handled differently in C++).
@@ -61,6 +85,84 @@ Polymer({
this.addWebUIListener('metrics-reporting-change', setMetricsReportingPref);
this.browserProxy_.getMetricsReporting().then(setMetricsReportingPref);
// </if>
+ // <if expr="not chromeos">
+ const storedAccountsChanged = storedAccounts => this.storedAccounts_ =
+ storedAccounts;
+ const syncBrowserProxy = settings.SyncBrowserProxyImpl.getInstance();
+ syncBrowserProxy.getStoredAccounts().then(storedAccountsChanged);
+ this.addWebUIListener('stored-accounts-updated', storedAccountsChanged);
+ // </if>
+
+ // Even though we already set checked="[[getCheckedLeakDetection_(...)]]"
+ // in the DOM, this might be overridden within prefValueChanged_ of
+ // SettingsBooleanControlBehaviorImpl which gets invoked once we navigate to
+ // sync_page.html. Re-computing the checked value here once fixes this
+ // problem.
+ this.$.passwordsLeakDetectionCheckbox.checked =
+ this.getCheckedLeakDetection_();
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ computeUserSignedIn_: function() {
+ return (!!this.syncStatus && !!this.syncStatus.signedIn) ?
+ !this.syncStatus.hasError :
+ (!!this.storedAccounts_ && this.storedAccounts_.length > 0);
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ computePasswordsLeakDetectionAvailable_: function() {
+ return !!this.getPref('profile.password_manager_leak_detection').value &&
+ !!this.getPref('safebrowsing.enabled').value;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ getCheckedLeakDetection_: function() {
+ return this.userSignedIn_ && this.passwordsLeakDetectionAvailable_;
+ },
+
+ /**
+ * @return {string}
+ * @private
+ */
+ getPasswordsLeakDetectionSubLabel_: function() {
+ if (!this.userSignedIn_ && this.passwordsLeakDetectionAvailable_) {
+ return this.i18n('passwordsLeakDetectionSignedOutEnabledDescription');
+ }
+ return '';
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ getDisabledLeakDetection_: function() {
+ return !this.userSignedIn_ || !this.getPref('safebrowsing.enabled').value;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ getCheckedExtendedSafeBrowsing_: function() {
+ return !!this.getPref('safebrowsing.enabled').value &&
+ !!this.getPref('safebrowsing.scout_reporting_enabled').value;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ getDisabledExtendedSafeBrowsing_: function() {
+ return !this.getPref('safebrowsing.enabled').value;
},
// <if expr="_google_chrome and not chromeos">
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 1ad29354d5c..9b9618c956d 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -303,6 +303,23 @@
</category-setting-exceptions>
</settings-subpage>
</template>
+ <template is="dom-if" if="[[enableInsecureContentContentSetting_]]">
+ <template is="dom-if" route-path="/content/insecureContent" no-search>
+ <settings-subpage
+ page-title="$i18n{siteSettingsCategoryInsecureContent}"
+ search-label="$i18n{siteSettingsAllSitesSearch}"
+ search-term="{{searchFilter_}}">
+ <div class="settings-box first">
+ $i18n{siteSettingsInsecureContentBlock}
+ </div>
+ <category-setting-exceptions
+ category="[[ContentSettingsTypes.MIXEDSCRIPT]]"
+ block-header="$i18n{siteSettingsBlock}"
+ search-filter="[[searchFilter_]]">
+ </category-setting-exceptions>
+ </settings-subpage>
+ </template>
+ </template>
<template is="dom-if" route-path="/content/location" no-search>
<settings-subpage page-title="$i18n{siteSettingsCategoryLocation}"
search-label="$i18n{siteSettingsAllSitesSearch}"
@@ -664,7 +681,7 @@
</settings-subpage>
</template>
</template>
- <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]">
+ <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]">
<template is="dom-if" route-path="/content/bluetoothScanning" no-search>
<settings-subpage page-title="$i18n{siteSettingsBluetoothScanning}"
search-label="$i18n{siteSettingsAllSitesSearch}"
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 57b42d06dee..a7b63fd525e 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -136,10 +136,10 @@ Polymer({
},
/** @private */
- enableBluetoothScanningContentSetting_: {
+ enableInsecureContentContentSetting_: {
type: Boolean,
value: function() {
- return loadTimeData.getBoolean('enableBluetoothScanningContentSetting');
+ return loadTimeData.getBoolean('enableInsecureContentContentSetting');
}
},
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
index 7569eead29a..e1d92c209a0 100644
--- 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
@@ -27,12 +27,20 @@
padding-inline-end: 12px;
}
+ .list-item .name {
+ word-break: break-word;
+ }
+
.name {
flex: 3;
}
- #dialog::part(body-container) {
- overflow-y: hidden;
+ .icon-placeholder {
+ width: var(--cr-icon-ripple-size);
+ }
+
+ #outer {
+ padding: 0 var(--cr-section-padding);
}
</style>
@@ -51,40 +59,53 @@
<div id="pinPrompt">
<p>$i18n{securityKeysBioEnrollmentPinPrompt}</p>
- <settings-security-keys-pin-field id="pin">
+ <settings-security-keys-pin-field
+ id="pin" label="$i18n{securityKeysPIN}">
</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>
+ <h2 class="start">$i18n{securityKeysBioEnrollmentLabel}</h2>
<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 id="outer">
+ <div id="header" class="list-item column-header"
+ hidden="[[!hasSome_(enrollments_)]]">
+ <div class="name">
+ $i18n{securityKeysBioEnrollmentNameLabel}
+ </div>
+ <div class="icon-placeholder"></div>
+ </div>
+
+ <div id="container" hidden="[[!hasSome_(enrollments_)]]">
+ <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>
- <cr-icon-button class="icon-clear"
- aria-label="i18n{securityKeysBioEnrollmentDelete}"
- on-click="deleteEnrollment_"
- disabled="[[deleteInProgress_]]">
- </cr-icon-button>
- </div>
- </template>
- </iron-list>
+ </template>
+ </iron-list>
+ </div>
+
+ <p hidden="[[hasSome_(enrollments_)]]">
+ $i18n{securityKeysBioEnrollmentNoEnrollments}
+ </p>
</div>
</div>
@@ -93,18 +114,31 @@
<cr-fingerprint-progress-arc id="arc"></cr-fingerprint-progress-arc>
</div>
+ <div id="chooseName">
+ <p>$i18n{securityKeysBioEnrollmentChooseName}</p>
+ <cr-input type="text" id="enrollmentName"
+ value="{{recentEnrollmentName_}}"
+ label="$i18n{securityKeysBioEnrollmentNameLabel}"
+ on-input="onEnrollmentNameInput_"
+ spellcheck="false">
+ </cr-input>
+ </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_]]">
+ <cr-button id="cancelButton" class="cancel-button" on-click="cancel_"
+ hidden="[[!cancelButtonVisible_]]"
+ disabled="[[cancelButtonDisabled_]]">
$i18n{cancel}
</cr-button>
- <cr-button id="okButton" class="action-button"
- on-click="okButtonClick_" hidden="[[!okButtonVisible_]]">
- $i18n{ok}
+ <cr-button id="confirmButton" class="action-button"
+ hidden="[[!confirmButtonVisible_]]"
+ disabled="[[confirmButtonDisabled_]]"
+ on-click="confirmButtonClick_">
+ $i18n{continue}
</cr-button>
<cr-button id="doneButton" class="action-button"
on-click="done_" hidden="[[!doneButtonVisible_]]">
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
index 1f251c65aa4..43253425f32 100644
--- 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
@@ -20,12 +20,18 @@ Polymer({
properties: {
/** @private */
- addButtonVisible_: Boolean,
+ cancelButtonDisabled_: Boolean,
/** @private */
cancelButtonVisible_: Boolean,
/** @private */
+ confirmButtonDisabled_: Boolean,
+
+ /** @private */
+ confirmButtonVisible_: Boolean,
+
+ /** @private */
deleteInProgress_: Boolean,
/**
@@ -48,14 +54,17 @@ Polymer({
enrollments_: Array,
/** @private */
- okButtonVisible_: Boolean,
+ recentEnrollmentName_: String,
},
/** @private {?settings.SecurityKeysBioEnrollProxyImpl} */
browserProxy_: null,
- /** @private */
- maxSamples_: Number,
+ /** @private {number} */
+ maxSamples_: -1,
+
+ /** @private {string} */
+ recentEnrollmentId_: '',
/** @override */
attached: function() {
@@ -65,8 +74,9 @@ Polymer({
this.addWebUIListener(
'security-keys-bio-enroll-status', this.onEnrolling_.bind(this));
this.browserProxy_ = settings.SecurityKeysBioEnrollProxyImpl.getInstance();
- this.browserProxy_.startBioEnroll().then(
- this.collectPIN_.bind(this), () => {});
+ this.browserProxy_.startBioEnroll().then(() => {
+ this.collectPIN_();
+ });
},
/** @private */
@@ -87,17 +97,17 @@ Polymer({
/** @private */
submitPIN_: function() {
if (!this.$.pin.validate()) {
+ this.confirmButtonDisabled_ = false;
return;
}
- this.browserProxy_.providePIN(this.$.pin.value).then((retries) => {
+ this.browserProxy_.providePIN(this.$.pin.value).then(retries => {
+ this.confirmButtonDisabled_ = false;
if (retries != null) {
this.$.pin.showIncorrectPINError(retries);
return;
}
-
- this.browserProxy_.enumerateEnrollments().then(
- this.onEnrollments_.bind(this));
- }, () => {});
+ this.showEnrollmentsPage_();
+ });
},
/**
@@ -114,33 +124,39 @@ Polymer({
dialogPageChanged_: function() {
switch (this.dialogPage_) {
case 'initial':
- this.addButtonVisible_ = false;
this.cancelButtonVisible_ = true;
- this.okButtonVisible_ = false;
+ this.cancelButtonDisabled = false;
+ this.confirmButtonVisible_ = false;
this.doneButtonVisible_ = false;
break;
case 'pinPrompt':
- this.addButtonVisible_ = false;
this.cancelButtonVisible_ = true;
- this.okButtonVisible_ = true;
+ this.cancelButtonDisabled = false;
+ this.confirmButtonVisible_ = true;
+ this.confirmButtonDisabled_ = false;
this.doneButtonVisible_ = false;
break;
case 'enrollments':
- this.addButtonVisible_ = true;
this.cancelButtonVisible_ = false;
- this.okButtonVisible_ = false;
+ this.confirmButtonVisible_ = false;
this.doneButtonVisible_ = true;
break;
case 'enroll':
- this.addButtonVisible_ = false;
this.cancelButtonVisible_ = true;
- this.okButtonVisible_ = false;
+ this.cancelButtonDisabled = false;
+ this.confirmButtonVisible_ = false;
+ this.doneButtonVisible_ = false;
+ break;
+ case 'chooseName':
+ this.cancelButtonVisible_ = false;
+ this.confirmButtonVisible_ = true;
+ this.confirmButtonDisabled_ = !this.recentEnrollmentName_.length;
this.doneButtonVisible_ = false;
+ this.$.enrollmentName.focus();
break;
case 'error':
- this.addButtonVisible_ = false;
this.cancelButtonVisible_ = false;
- this.okButtonVisible_ = false;
+ this.confirmButtonVisible_ = false;
this.doneButtonVisible_ = true;
break;
default:
@@ -155,12 +171,15 @@ Polymer({
this.maxSamples_ = -1; // Reset maxSamples_ before enrolling starts.
this.$.arc.reset();
- this.cancelButtonVisible_ = true;
- this.okButtonVisible_ = false;
+
+ this.recentEnrollmentId_ = '';
+ this.recentEnrollmentName_ = '';
this.dialogPage_ = 'enroll';
- this.browserProxy_.startEnrolling().then(
- this.onEnrolling_.bind(this), () => {});
+
+ this.browserProxy_.startEnrolling().then(response => {
+ this.onEnrolling_(response);
+ });
},
/**
@@ -168,6 +187,11 @@ Polymer({
* @param {!EnrollmentStatus} response
*/
onEnrolling_: function(response) {
+ if (response.code == Ctap2Status.ERR_KEEPALIVE_CANCEL) {
+ this.showEnrollmentsPage_();
+ return;
+ }
+
if (this.maxSamples_ == -1 && response.status != null) {
if (response.status == 0) {
// If the first sample is valid, remaining is one less than max samples
@@ -186,21 +210,37 @@ Polymer({
100 - (100 * response.remaining / this.maxSamples_),
response.remaining == 0);
if (response.remaining == 0) {
+ assert(response.enrollment);
+ this.recentEnrollmentId_ = response.enrollment.id;
+ this.recentEnrollmentName_ = response.enrollment.name;
this.cancelButtonVisible_ = false;
- this.okButtonVisible_ = true;
+ this.confirmButtonVisible_ = true;
+ this.confirmButtonDisabled_ = false;
+ this.$.confirmButton.focus();
}
this.fire('bio-enroll-dialog-ready-for-testing');
},
/** @private */
- okButtonClick_: function() {
+ confirmButtonClick_: function() {
+ // Disable |confirmButton| while PIN verification or template enumeration is
+ // pending. Resetting |dialogPage_| will re-enable it.
+ this.confirmButtonDisabled_ = true;
switch (this.dialogPage_) {
case 'pinPrompt':
this.submitPIN_();
break;
case 'enroll':
- this.browserProxy_.enumerateEnrollments().then(
- this.onEnrollments_.bind(this), () => {});
+ assert(!!this.recentEnrollmentId_.length);
+ this.dialogPage_ = 'chooseName';
+ break;
+ case 'chooseName':
+ this.browserProxy_
+ .renameEnrollment(
+ this.recentEnrollmentId_, this.recentEnrollmentName_)
+ .then(enrollments => {
+ this.onEnrollments_(enrollments);
+ });
break;
default:
assertNotReached();
@@ -208,24 +248,27 @@ Polymer({
},
/** @private */
+ showEnrollmentsPage_: function() {
+ this.browserProxy_.enumerateEnrollments().then(enrollments => {
+ this.onEnrollments_(enrollments);
+ });
+ },
+
+ /** @private */
cancel_: function() {
if (this.dialogPage_ == 'enroll') {
- this.browserProxy_.cancelEnrollment().then(
- this.cancelEnroll_.bind(this), () => {});
+ // Cancel an ongoing enrollment. Will cause the pending
+ // enumerateEnrollments() promise to be resolved and proceed to the
+ // enrollments page.
+ this.cancelButtonDisabled_ = true;
+ this.browserProxy_.cancelEnrollment();
} else {
+ // On any other screen, simply close the dialog.
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();
},
@@ -268,6 +311,11 @@ Polymer({
this.deleteInProgress_ = false;
this.onEnrollments_(enrollments);
});
- }
+ },
+
+ /** @private */
+ onEnrollmentNameInput_: function() {
+ this.confirmButtonDisabled_ = !this.recentEnrollmentName_.length;
+ },
});
})();
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 00a55d9f52d..ba01514b632 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
@@ -5,6 +5,16 @@
cr.exportPath('settings');
/**
+ * Ctap2Status contains a subset of CTAP2 status codes. See
+ * device::CtapDeviceResponseCode for the full list.
+ * @enum{number}
+ */
+const Ctap2Status = {
+ OK: 0x0,
+ ERR_KEEPALIVE_CANCEL: 0x2D,
+};
+
+/**
* Credential represents a CTAP2 resident credential enumerated from a security
* key.
*
@@ -28,15 +38,19 @@ 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.
+ * where 'remaining' is the number of samples left, 'status' is the last
+ * enrollment status, 'code' indicates the final CtapDeviceResponseCode of the
+ * operation, and 'enrollment' contains the new Enrollment.
+ *
* 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.
+ * reaches an end state, 'code' and, if successful, 'enrollment' are set. |OK|
+ * indicates successful enrollment. A code of |ERR_KEEPALIVE_CANCEL| indicates
+ * user-initated cancellation.
*
* @typedef {{status: ?number,
- * code: ?number,
- * remaining: number}}
+ * code: ?Ctap2Status,
+ * remaining: number,
+ * enrollment: ?Enrollment}}
* @see chrome/browser/ui/webui/settings/settings_security_key_handler.cc
*/
let EnrollmentStatus;
@@ -197,9 +211,6 @@ cr.define('settings', function() {
* 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() {}
@@ -211,6 +222,15 @@ cr.define('settings', function() {
*/
deleteEnrollment(id) {}
+ /**
+ * Renames the enrollment with the given ID.
+ *
+ * @param {string} id
+ * @param {string} name
+ * @return {!Promise<!Array<!Enrollment>>} The updated list of enrollments.
+ */
+ renameEnrollment(id, name) {}
+
/** Cancels all outstanding operations. */
close() {}
}
@@ -303,7 +323,7 @@ cr.define('settings', function() {
/** @override */
cancelEnrollment() {
- return cr.sendWithPromise('securityKeyBioEnrollCancel');
+ return chrome.send('securityKeyBioEnrollCancel');
}
/** @override */
@@ -312,6 +332,11 @@ cr.define('settings', function() {
}
/** @override */
+ renameEnrollment(id, name) {
+ return cr.sendWithPromise('securityKeyBioEnrollRename', id, name);
+ }
+
+ /** @override */
close() {
return chrome.send('securityKeyBioEnrollClose');
}
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 0045f54d6a2..070ed2d6abb 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
@@ -69,7 +69,8 @@
<div id="pinPrompt">
<p>$i18nRaw{securityKeysCredentialManagementPinPrompt}</p>
- <settings-security-keys-pin-field id="pin">
+ <settings-security-keys-pin-field
+ id="pin" label="$i18n{securityKeysPIN}">
</settings-security-keys-pin-field>
</div>
@@ -92,9 +93,9 @@
</div>
<div class="user">[[formatUser_(item)]]</div>
<cr-checkbox on-change="checkedCredentialsChanged_"
- data-id$="[[item.id]]"
- checked="[[credentialIsChecked_(item.id)]]"
- disabled="[[deleteInProgress_]]"></cr-checkbox>
+ data-id$="[[item.id]]"
+ checked="[[credentialIsChecked_(item.id)]]"
+ disabled="[[deleteInProgress_]]"></cr-checkbox>
</div>
</template>
</iron-list>
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 146f22674b3..062c329e254 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
@@ -98,7 +98,9 @@ Polymer({
if (!this.$.pin.validate()) {
return;
}
+ this.confirmButtonDisabled_ = true;
this.browserProxy_.providePIN(this.$.pin.value).then((retries) => {
+ this.confirmButtonDisabled_ = false;
if (retries != null) {
this.$.pin.showIncorrectPINError(retries);
this.collectPin_();
@@ -258,9 +260,11 @@ Polymer({
assert(this.credentials_ && this.credentials_.length > 0);
assert(this.checkedCredentialIds_.size > 0);
+ this.confirmButtonDisabled_ = true;
this.deleteInProgress_ = true;
this.browserProxy_.deleteCredentials(Array.from(this.checkedCredentialIds_))
.then((err) => {
+ this.confirmButtonDisabled_ = false;
this.deleteInProgress_ = false;
this.onError_(err);
});
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html
index bd62a4001c0..f185cba1363 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html
@@ -3,6 +3,7 @@
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.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-a11y-announcer/iron-a11y-announcer.html">
<link rel="import" href="../i18n_setup.html">
<link rel="import" href="../settings_shared_css.html">
diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js
index abace08a7e0..72159d830d7 100644
--- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js
+++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js
@@ -18,7 +18,10 @@ Polymer({
label: String,
/** The validation error label of the input field. */
- error: String,
+ error: {
+ type: String,
+ observer: 'errorChanged_',
+ },
/** The value of the input field. */
value: String,
@@ -32,6 +35,10 @@ Polymer({
/** @override */
attached: function() {
+ Polymer.RenderStatus.afterNextRender(this, function() {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ });
+
this.inputVisible_ = false;
},
@@ -158,4 +165,11 @@ Polymer({
return '';
},
+
+ /** @private */
+ errorChanged_: function() {
+ // Make screen readers announce changes to the PIN validation error
+ // label.
+ this.fire('iron-announce', {text: this.error});
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/route.js b/chromium/chrome/browser/resources/settings/route.js
index 244cb3be580..091bb933e2e 100644
--- a/chromium/chrome/browser/resources/settings/route.js
+++ b/chromium/chrome/browser/resources/settings/route.js
@@ -13,6 +13,8 @@
* ACCOUNT_MANAGER: (undefined|!settings.Route),
* ADVANCED: (undefined|!settings.Route),
* ADDRESSES: (undefined|!settings.Route),
+ * APP_MANAGEMENT: (undefined|!settings.Route),
+ * APP_MANAGEMENT_DETAIL: (undefined|!settings.Route),
* APPS: (undefined|!settings.Route),
* ANDROID_APPS: (undefined|!settings.Route),
* ANDROID_APPS_DETAILS: (undefined|!settings.Route),
@@ -58,6 +60,7 @@
* LANGUAGES_DETAILS: (undefined|!settings.Route),
* LOCK_SCREEN: (undefined|!settings.Route),
* MANAGE_ACCESSIBILITY: (undefined|!settings.Route),
+ * MANAGE_CAPTION_SETTINGS: (undefined|!settings.Route),
* MANAGE_PROFILE: (undefined|!settings.Route),
* MANAGE_SWITCH_ACCESS_SETTINGS: (undefined|!settings.Route),
* MANAGE_TTS_SETTINGS: (undefined|!settings.Route),
@@ -95,6 +98,7 @@
* SITE_SETTINGS_FLASH: (undefined|!settings.Route),
* SITE_SETTINGS_HANDLERS: (undefined|!settings.Route),
* SITE_SETTINGS_IMAGES: (undefined|!settings.Route),
+ * SITE_SETTINGS_MIXEDSCRIPT: (undefined|!settings.Route),
* SITE_SETTINGS_JAVASCRIPT: (undefined|!settings.Route),
* SITE_SETTINGS_SENSORS: (undefined|!settings.Route),
* SITE_SETTINGS_SOUND: (undefined|!settings.Route),
@@ -326,6 +330,10 @@ cr.define('settings', function() {
r.SITE_SETTINGS_DATA_DETAILS =
r.SITE_SETTINGS_SITE_DATA.createChild('/cookies/detail');
r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild('images');
+ if (loadTimeData.getBoolean('enableInsecureContentContentSetting')) {
+ r.SITE_SETTINGS_MIXEDSCRIPT =
+ r.SITE_SETTINGS.createChild('insecureContent');
+ }
r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild('javascript');
r.SITE_SETTINGS_SOUND = r.SITE_SETTINGS.createChild('sound');
r.SITE_SETTINGS_SENSORS = r.SITE_SETTINGS.createChild('sensors');
@@ -352,7 +360,7 @@ cr.define('settings', function() {
r.SITE_SETTINGS_PAYMENT_HANDLER =
r.SITE_SETTINGS.createChild('paymentHandler');
}
- if (loadTimeData.getBoolean('enableBluetoothScanningContentSetting')) {
+ if (loadTimeData.getBoolean('enableExperimentalWebPlatformFeatures')) {
r.SITE_SETTINGS_BLUETOOTH_SCANNING =
r.SITE_SETTINGS.createChild('bluetoothScanning');
}
@@ -453,7 +461,10 @@ cr.define('settings', function() {
r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint');
}
- if (loadTimeData.valueExists('androidAppsVisible') &&
+ // Show Android Apps page in the browser if split settings is turned off.
+ if (!loadTimeData.getBoolean('isOSSettings') &&
+ loadTimeData.getBoolean('showOSSettings') &&
+ loadTimeData.valueExists('androidAppsVisible') &&
loadTimeData.getBoolean('androidAppsVisible')) {
r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps');
r.ANDROID_APPS_DETAILS =
@@ -524,13 +535,21 @@ cr.define('settings', function() {
r.RESET = r.ADVANCED.createSection('/reset', 'reset');
}
+ const showAppManagement = loadTimeData.valueExists('showAppManagement') &&
+ loadTimeData.getBoolean('showAppManagement');
+ const showAndroidApps = loadTimeData.valueExists('androidAppsVisible') &&
+ loadTimeData.getBoolean('androidAppsVisible');
// Apps
- if (loadTimeData.valueExists('showApps') &&
- loadTimeData.getBoolean('showApps')) {
+ if (showAppManagement || showAndroidApps) {
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');
+ if (showAppManagement) {
+ r.APP_MANAGEMENT = r.APPS.createChild('/app-management');
+ r.APP_MANAGEMENT_DETAIL =
+ r.APP_MANAGEMENT.createChild('/app-management/detail');
+ }
+ if (showAndroidApps) {
+ r.ANDROID_APPS_DETAILS = r.APPS.createChild('/androidAppsDetails');
+ }
}
} else {
assert(r.ADVANCED, 'ADVANCED route should exist');
@@ -573,6 +592,9 @@ cr.define('settings', function() {
}
r.MANAGE_TTS_SETTINGS =
r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts');
+
+ r.MANAGE_CAPTION_SETTINGS =
+ r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/captions');
}
// </if>
@@ -727,12 +749,16 @@ cr.define('settings', function() {
* Initialize the route and query params from the URL.
*/
initializeRouteFromUrl() {
- this.recordMetrics(window.location.pathname);
-
assert(!this.initializeRouteFromUrlCalled_);
this.initializeRouteFromUrlCalled_ = true;
const route = this.getRouteForPath(window.location.pathname);
+
+ // Record all correct paths entered on the settings page, and
+ // as all incorrect paths are routed to the main settings page,
+ // record all incorrect paths as hitting the main settings page.
+ this.recordMetrics(route ? route.path : this.routes_.BASIC.path);
+
// Never allow direct navigation to ADVANCED.
if (route && route != this.routes_.ADVANCED) {
this.currentRoute = route;
@@ -751,6 +777,7 @@ cr.define('settings', function() {
assert(!urlPath.startsWith('chrome://'));
assert(!urlPath.startsWith('settings'));
assert(urlPath.startsWith('/'));
+ assert(!urlPath.match(/\?/g));
chrome.metricsPrivate.recordSparseHashable(
'WebUI.Settings.PathVisited', urlPath);
}
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 83d8b346ed4..4469b4298cc 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,10 @@
<div class="list-item" focus-row-container>
<div id="name-column">
- <site-favicon favicon-url="[[engine.iconURL]]"></site-favicon>
+ <site-favicon
+ favicon-url="[[engine.iconURL]]"
+ url="[[engine.url]]">
+ </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 a98f501303f..60facec8de0 100644
--- a/chromium/chrome/browser/resources/settings/search_settings.js
+++ b/chromium/chrome/browser/resources/settings/search_settings.js
@@ -149,11 +149,15 @@ cr.define('settings', function() {
let associatedControl = null;
// Find corresponding SETTINGS-SECTION parent and make it visible.
let parent = node;
- while (parent && parent.nodeName !== 'SETTINGS-SECTION') {
+ while (parent.nodeName !== 'SETTINGS-SECTION') {
parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
parent.host :
parent.parentNode;
- if (parent && parent.nodeName == 'SETTINGS-SUBPAGE') {
+ if (!parent) {
+ // |node| wasn't inside a SETTINGS-SECTION.
+ return null;
+ }
+ if (parent.nodeName == 'SETTINGS-SUBPAGE') {
// TODO(dpapad): Cast to SettingsSubpageElement here.
associatedControl = assert(
parent.associatedControl,
@@ -161,9 +165,7 @@ cr.define('settings', function() {
parent.pageTitle + ', but was not found.');
}
}
- if (parent) {
- parent.hiddenBySearch = false;
- }
+ parent.hiddenBySearch = false;
// Need to add the search bubble after the parent SETTINGS-SECTION has
// become visible, otherwise |offsetWidth| returns zero.
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 4dabc3f833b..0bcf8487656 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -176,7 +176,8 @@
<iron-icon icon="settings:power-settings-new"></iron-icon>
$i18n{onStartup}
</a>
- <cr-button id="advancedButton" aria-active-attribute="aria-expanded"
+ <cr-button id="advancedButton"
+ aria-expanded$="[[boolToString_(advancedOpened)]]"
on-click="onAdvancedButtonToggle_"
hidden="[[!pageVisibility.advancedSettings]]">
<span>$i18n{advancedPageTitle}</span>
diff --git a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js
index 38bce70ccb4..c604ae4bcbf 100644
--- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js
+++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -27,12 +27,12 @@ Polymer({
/** @param {!settings.Route} newRoute */
currentRouteChanged: function(newRoute) {
- const currentPath = newRoute.path;
-
// Focus the initially selected path.
const anchors = this.root.querySelectorAll('a');
for (let i = 0; i < anchors.length; ++i) {
- if (anchors[i].getAttribute('href') == currentPath) {
+ const anchorRoute =
+ settings.router.getRouteForPath(anchors[i].getAttribute('href'));
+ if (anchorRoute && anchorRoute.contains(newRoute)) {
this.setSelectedUrl_(anchors[i].href);
return;
}
@@ -95,4 +95,13 @@ Polymer({
chrome.metricsPrivate.recordUserAction(
'SettingsMenu_ExtensionsLinkClicked');
},
+
+ /**
+ * @param {boolean} bool
+ * @return {string}
+ * @private
+ */
+ boolToString_: function(bool) {
+ return bool.toString();
+ },
});
diff --git a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn
index f6f20fe035e..ac38ed67f66 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn
@@ -33,7 +33,7 @@ js_library("settings_animated_pages") {
"//ui/webui/resources/js:util",
"//ui/webui/resources/js/cr/ui:focus_without_ink",
]
- externs_list = [ "$externs_path/pending.js" ]
+ externs_list = [ "$externs_path/pending_polymer.js" ]
}
js_library("settings_section") {
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 c48064bcaf2..b4ea404e35f 100644
--- a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html
+++ b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -75,7 +75,7 @@
<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]]">
+ <img id="title-icon" src="[[titleIcon]]" aria-hidden="true">
</template>
<h1 class="cr-title-text">[[pageTitle]]</h1>
<slot name="subpage-title-extra"></slot>
diff --git a/chromium/chrome/browser/resources/settings/settings_resources.grd b/chromium/chrome/browser/resources/settings/settings_resources.grd
index 14f631a9af7..ea0b1a1026a 100644
--- a/chromium/chrome/browser/resources/settings/settings_resources.grd
+++ b/chromium/chrome/browser/resources/settings/settings_resources.grd
@@ -563,12 +563,6 @@
<structure name="IDR_SETTINGS_DEVICE_DISPLAY_OVERSCAN_DIALOG_JS"
file="device_page/display_overscan_dialog.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_HTML"
- file="device_page/drive_cache_dialog.html"
- type="chrome_html" />
- <structure name="IDR_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_JS"
- file="device_page/drive_cache_dialog.js"
- type="chrome_html" />
<structure name="IDR_SETTINGS_DEVICE_KEYBOARD_HTML"
file="device_page/keyboard.html"
type="chrome_html" />
@@ -987,11 +981,17 @@
<structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_JS"
file="printing_page/cups_printers_entry.js"
type="chrome_html" />
- <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_HTML"
- file="printing_page/cups_printers_entry_list.html"
+ <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_HTML"
+ file="printing_page/cups_printers_entry_list_behavior.html"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_JS"
+ file="printing_page/cups_printers_entry_list_behavior.js"
+ type="chrome_html" />
+ <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_HTML"
+ file="printing_page/cups_printers_entry_manager.html"
type="chrome_html" />
- <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_JS"
- file="printing_page/cups_printers_entry_list.js"
+ <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_JS"
+ file="printing_page/cups_printers_entry_manager.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_CUPS_PRINTERS_LIST_HTML"
file="printing_page/cups_printers_list.html"
diff --git a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn
index ae564bee278..8cbb5556ae7 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn
+++ b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn
@@ -17,7 +17,7 @@ js_library("settings_ui") {
"../prefs",
"../settings_main:settings_main",
"//ui/webui/resources/cr_elements:cr_container_shadow_behavior",
- "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types",
+ "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings",
"//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",
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 286257d15ea..5f25212f6be 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -21,7 +21,7 @@
<link rel="import" href="../settings_vars_css.html">
<if expr="chromeos">
-<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html">
+<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_strings.html">
</if>
<dom-module id="settings-ui">
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 fdbbef286d5..f3b8d60d861 100644
--- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
+++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -152,8 +152,12 @@ Polymer({
loadTimeData.getString('networkListItemConnectingTo'),
networkListItemInitializing:
loadTimeData.getString('networkListItemInitializing'),
+ networkListItemNotAvailable:
+ loadTimeData.getString('networkListItemNotAvailable'),
networkListItemScanning:
loadTimeData.getString('networkListItemScanning'),
+ networkListItemSimCardLocked:
+ loadTimeData.getString('networkListItemSimCardLocked'),
networkListItemNotConnected:
loadTimeData.getString('networkListItemNotConnected'),
networkListItemNoNetwork:
diff --git a/chromium/chrome/browser/resources/settings/site_favicon.js b/chromium/chrome/browser/resources/settings/site_favicon.js
index e905bd54e35..b6d516d0e71 100644
--- a/chromium/chrome/browser/resources/settings/site_favicon.js
+++ b/chromium/chrome/browser/resources/settings/site_favicon.js
@@ -17,7 +17,7 @@ Polymer({
/** @private */
getBackgroundImage_: function() {
- let backgroundImage = 'none';
+ let backgroundImage = cr.icon.getFavicon('');
if (this.faviconUrl) {
const url = this.ensureUrlHasScheme_(this.faviconUrl);
backgroundImage = cr.icon.getFavicon(url);
diff --git a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html
index 938cfebaeac..6b38253df50 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html
@@ -30,6 +30,10 @@
contentSetting)]]">
$i18n{incognitoSiteOnly}
</cr-checkbox>
+ <cr-checkbox id="thirdParties"
+ hidden$="[[shouldHideThirdPartyCookieCheckbox_(category)]]">
+ $i18n{siteSettingsCookiesThirdPartyExceptionLabel}
+ </cr-checkbox>
</div>
<div slot="button-container">
<cr-button class="cancel-button" on-click="onCancelTap_">
diff --git a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js
index 973e15fca05..a9962dde633 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js
@@ -86,9 +86,18 @@ Polymer({
*/
onSubmit_: function() {
assert(!this.$.add.disabled);
+ let primaryPattern = this.site_;
+ let secondaryPattern = settings.SITE_EXCEPTION_WILDCARD;
+
+ if (this.$.thirdParties.checked) {
+ primaryPattern = settings.SITE_EXCEPTION_WILDCARD;
+ secondaryPattern = this.site_;
+ }
+
this.browserProxy.setCategoryPermissionForPattern(
- this.site_, this.site_, this.category, this.contentSetting,
+ primaryPattern, secondaryPattern, this.category, this.contentSetting,
this.$.incognito.checked);
+
this.$.dialog.close();
},
@@ -104,4 +113,13 @@ Polymer({
this.$.incognito.checked = false;
}
},
+
+ /**
+ * @return {boolean}
+ * @private
+ */
+ shouldHideThirdPartyCookieCheckbox_: function() {
+ return this.category !== settings.ContentSettingsTypes.COOKIES ||
+ !loadTimeData.getBoolean('showImprovedCookieControlsForThirdParties');
+ },
});
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 554bc6992dc..a3e2d3277eb 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
@@ -103,6 +103,7 @@ Polymer({
case settings.ContentSettingsTypes.BACKGROUND_SYNC:
case settings.ContentSettingsTypes.IMAGES:
case settings.ContentSettingsTypes.JAVASCRIPT:
+ case settings.ContentSettingsTypes.MIXEDSCRIPT:
case settings.ContentSettingsTypes.SOUND:
case settings.ContentSettingsTypes.SENSORS:
case settings.ContentSettingsTypes.PAYMENT_HANDLER:
@@ -176,10 +177,22 @@ Polymer({
if (update.source !== undefined &&
update.source != ContentSettingProvider.PREFERENCE) {
basePref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED;
- basePref.controlledBy =
- update.source == ContentSettingProvider.EXTENSION ?
- chrome.settingsPrivate.ControlledBy.EXTENSION :
- chrome.settingsPrivate.ControlledBy.USER_POLICY;
+ switch (update.source) {
+ case ContentSettingProvider.POLICY:
+ basePref.controlledBy =
+ chrome.settingsPrivate.ControlledBy.DEVICE_POLICY;
+ break;
+ case ContentSettingProvider.SUPERVISED_USER:
+ basePref.controlledBy = chrome.settingsPrivate.ControlledBy.PARENT;
+ break;
+ case ContentSettingProvider.EXTENSION:
+ basePref.controlledBy = chrome.settingsPrivate.ControlledBy.EXTENSION;
+ break;
+ default:
+ basePref.controlledBy =
+ chrome.settingsPrivate.ControlledBy.USER_POLICY;
+ break;
+ }
}
const prefValue = this.computeIsSettingEnabled(update.setting);
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 01d7cb15355..6fb8781c59a 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
@@ -1,7 +1,9 @@
<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="constants.html">
<link rel="import" href="site_list.html">
+<link rel="import" href="site_settings_prefs_browser_proxy.html">
<dom-module id="category-setting-exceptions">
<template>
@@ -9,7 +11,7 @@
category="[[category]]"
category-subtype="[[ContentSetting.BLOCK]]"
category-header="[[blockHeader]]"
- read-only-list="[[readOnlyList]]"
+ read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]"
search-filter="[[searchFilter]]"
hidden$="[[!showBlockSiteList_]]">
</site-list>
@@ -17,14 +19,14 @@
category="[[category]]"
category-subtype="[[ContentSetting.SESSION_ONLY]]"
category-header="$i18n{siteSettingsSessionOnly}"
- read-only-list="[[readOnlyList]]"
+ read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]"
search-filter="[[searchFilter]]">
</site-list>
<site-list
category="[[category]]"
category-subtype="[[ContentSetting.ALLOW]]"
category-header="$i18n{siteSettingsAllow}"
- read-only-list="[[readOnlyList]]"
+ read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]"
search-filter="[[searchFilter]]"
hidden$="[[!showAllowSiteList_]]">
</site-list>
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 212204450a9..44997259653 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
@@ -10,6 +10,8 @@
Polymer({
is: 'category-setting-exceptions',
+ behaviors: [SiteSettingsBehavior, WebUIListenerBehavior],
+
properties: {
/**
@@ -30,6 +32,12 @@ Polymer({
},
/**
+ * True if the default value is managed by a policy.
+ * @private
+ */
+ defaultManaged_: Boolean,
+
+ /**
* The heading text for the blocked exception list.
*/
blockHeader: String,
@@ -54,9 +62,15 @@ Polymer({
},
},
+ observers: [
+ 'updateDefaultManaged_(category)',
+ ],
+
/** @override */
ready: function() {
this.ContentSetting = settings.ContentSetting;
+ this.addWebUIListener(
+ 'contentSettingCategoryChanged', this.updateDefaultManaged_.bind(this));
},
/**
@@ -69,4 +83,32 @@ Polymer({
return this.category !=
settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE;
},
+
+ /**
+ * Updates whether or not the default value is managed by a policy.
+ * @private
+ */
+ updateDefaultManaged_: function() {
+ if (this.category === undefined) {
+ return;
+ }
+
+ this.browserProxy.getDefaultValueForContentType(this.category)
+ .then(update => {
+ this.defaultManaged_ =
+ update.source === settings.SiteSettingSource.POLICY;
+ });
+ },
+
+ /**
+ * Returns true if this list is explicitly marked as readonly by a consumer
+ * of this component or if the default value for these exceptions are managed
+ * by a policy. User should not be able to set exceptions to managed default
+ * values.
+ * @return {boolean}
+ * @private
+ */
+ getReadOnlyList_: function() {
+ return this.readOnlyList || this.defaultManaged_;
+ }
});
diff --git a/chromium/chrome/browser/resources/settings/site_settings/constants.js b/chromium/chrome/browser/resources/settings/site_settings/constants.js
index a7cf78b84ad..f073aa9b3db 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/constants.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/constants.js
@@ -36,6 +36,7 @@ settings.ContentSettingsTypes = {
CLIPBOARD: 'clipboard',
SENSORS: 'sensors',
PAYMENT_HANDLER: 'payment-handler',
+ MIXEDSCRIPT: 'mixed-script',
BLUETOOTH_SCANNING: 'bluetooth-scanning',
NATIVE_FILE_SYSTEM_WRITE: 'native-file-system-write',
};
@@ -121,3 +122,10 @@ settings.SortMethod = {
MOST_VISITED: 'most-visited',
STORAGE: 'data-stored',
};
+
+/**
+ * String representation of the wildcard used for universal
+ * match for SiteExceptions.
+ * @type {string}
+ */
+settings.SITE_EXCEPTION_WILDCARD = '*';
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 9fc485db610..f1a028c92b5 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_data.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.html
@@ -44,7 +44,7 @@
</cr-button>
<cr-button disabled$="[[isLoading_]]" id="removeThirdPartyCookies"
on-click="onRemoveThirdPartyCookiesTap_"
- hidden$="[[!enableRemovingAllThirdPartyCookies_]]">
+ hidden$="[[!showRemoveThirdPartyCookies_(sites.length, filter)]]">
$i18n{siteSettingsCookieRemoveAllThirdParty}
</cr-button>
</div>
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 644aedc4ac0..cd6370aa91c 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_data.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.js
@@ -75,15 +75,6 @@ Polymer({
/** @private */
listBlurred_: Boolean,
-
- /** @private */
- enableRemovingAllThirdPartyCookies_: {
- type: Boolean,
- value: function() {
- return loadTimeData.getBoolean('enableRemovingAllThirdPartyCookies') &&
- (this.sites.length > 0);
- }
- },
},
/** @private {settings.LocalDataBrowserProxy} */
@@ -287,4 +278,13 @@ Polymer({
new URLSearchParams('site=' + event.model.item.site));
this.lastSelected_ = event.model;
},
+
+ /**
+ * @private
+ * @return {boolean}
+ */
+ showRemoveThirdPartyCookies_: function() {
+ return loadTimeData.getBoolean('enableRemovingAllThirdPartyCookies') &&
+ this.sites.length > 0 && this.filter.length == 0;
+ },
});
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 1472652cc9e..fb24557a8e0 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.html
@@ -207,13 +207,20 @@
icon="settings:payment-handler" id="paymentHandler"
label="$i18n{siteSettingsPaymentHandler}">
</site-details-permission>
- <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]">
+ <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]">
<site-details-permission
category="{{ContentSettingsTypes.BLUETOOTH_SCANNING}}"
icon="settings:bluetooth-scanning" id="bluetoothScanning"
label="$i18n{siteSettingsBluetoothScanning}">
</site-details-permission>
</template>
+ <template is="dom-if" if="[[enableInsecureContentContentSetting_]]">
+ <site-details-permission
+ category="{{ContentSettingsTypes.MIXEDSCRIPT}}"
+ icon="settings:insecure-content" id="mixed-script"
+ label="$i18n{siteSettingsInsecureContent}">
+ </site-details-permission>
+ </template>
</div>
<website-usage-private-api id="usageApi"
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 875533a5f19..df765e0e3af 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_details.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.js
@@ -63,19 +63,19 @@ Polymer({
},
/** @private */
- enableBluetoothScanningContentSetting_: {
+ enableNativeFileSystemWriteContentSetting_: {
type: Boolean,
value: function() {
- return loadTimeData.getBoolean('enableBluetoothScanningContentSetting');
+ return loadTimeData.getBoolean(
+ 'enableNativeFileSystemWriteContentSetting');
}
},
/** @private */
- enableNativeFileSystemWriteContentSetting_: {
+ enableInsecureContentContentSetting_: {
type: Boolean,
value: function() {
- return loadTimeData.getBoolean(
- 'enableNativeFileSystemWriteContentSetting');
+ return loadTimeData.getBoolean('enableInsecureContentContentSetting');
}
},
},
@@ -185,7 +185,9 @@ Polymer({
exceptionList.forEach((exception, i) => {
// |exceptionList| should be in the same order as
// |categoryList|.
- permissionsMap[categoryList[i]].site = exception;
+ if (permissionsMap[categoryList[i]]) {
+ permissionsMap[categoryList[i]].site = exception;
+ }
});
// The displayName won't change, so just use the first
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html
index f296bf59503..da644580de1 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html
@@ -36,16 +36,17 @@
<site-favicon url="[[model.origin]]"></site-favicon>
<div class="middle no-min-width">
<div class="text-elide">
- <span class="url-directionality">[[model.displayName]]</span>
+ <span class="url-directionality">[[computeDisplayName_(model)]]
+ </span>
</div>
<!-- This div must not contain extra whitespace. -->
<div class="secondary text-elide"
- id="siteDescription">[[siteDescription_]]</div>
+ id="siteDescription">[[computeSiteDescription_(model)]]</div>
</div>
<template is="dom-if" if="[[allowNavigateToSiteDetail_]]">
<cr-icon-button class="subpage-arrow"
- aria-label$="[[model.displayName]]"
+ aria-label$="[[computeDisplayName_(model)]]"
aria-describedby="siteDescription" focus-row-control
focus-type="site-details"></cr-icon-button>
<div class="separator"></div>
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js
index fda7071af91..b296f31a34a 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js
@@ -55,12 +55,6 @@ Polymer({
},
/** @private */
- siteDescription_: {
- type: String,
- computed: 'computeSiteDescription_(model)',
- },
-
- /** @private */
showPolicyPrefIndicator_: {
type: Boolean,
computed: 'computeShowPolicyPrefIndicator_(model)',
@@ -126,34 +120,59 @@ Polymer({
},
/**
+ * Returns the appropriate display name to show for the exception.
+ * This can, for example, be the website that is affected itself,
+ * or the website whose third parties are also affected.
+ * @return {string}
+ */
+ computeDisplayName_: function() {
+ if (this.model.embeddingOrigin &&
+ this.model.category === settings.ContentSettingsTypes.COOKIES &&
+ this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) {
+ return this.model.embeddingOrigin;
+ }
+ return this.model.displayName;
+ },
+
+ /**
* Returns the appropriate site description to display. This can, for example,
* be blank, an 'embedded on <site>' or 'Current incognito session' (or a
* mix of the last two).
- * @return {string} The site description.
+ * @return {string}
*/
computeSiteDescription_: function() {
- let displayName = '';
+ let description = '';
+
if (this.model.embeddingOrigin) {
- displayName = loadTimeData.getStringF(
- 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin));
+ if (this.model.category === settings.ContentSettingsTypes.COOKIES &&
+ this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) {
+ description =
+ loadTimeData.getString(
+ 'siteSettingsCookiesThirdPartyExceptionLabel');
+ } else {
+ description = loadTimeData.getStringF(
+ 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin));
+ }
} else if (this.category == settings.ContentSettingsTypes.GEOLOCATION) {
- displayName = loadTimeData.getString('embeddedOnAnyHost');
+ description = loadTimeData.getString('embeddedOnAnyHost');
}
// <if expr="chromeos">
if (this.model.category === settings.ContentSettingsTypes.NOTIFICATIONS &&
this.model.showAndroidSmsNote) {
- displayName = loadTimeData.getString('androidSmsNote');
+ description = loadTimeData.getString('androidSmsNote');
}
// </if>
if (this.model.incognito) {
- if (displayName.length > 0) {
- return loadTimeData.getStringF('embeddedIncognitoSite', displayName);
+ if (description.length > 0) {
+ description =
+ loadTimeData.getStringF('embeddedIncognitoSite', description);
+ } else {
+ description = loadTimeData.getString('incognitoSite');
}
- return loadTimeData.getString('incognitoSite');
}
- return displayName;
+ return description;
},
/**
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 af45a352e33..545c49afcba 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
@@ -196,17 +196,20 @@ const SiteSettingsBehaviorImpl = {
settings.ContentSettingsTypes.SERIAL_PORTS,
'enableExperimentalWebPlatformFeatures');
addOrRemoveSettingWithFlag(
+ settings.ContentSettingsTypes.BLUETOOTH_SCANNING,
+ 'enableExperimentalWebPlatformFeatures');
+ addOrRemoveSettingWithFlag(
settings.ContentSettingsTypes.ADS,
'enableSafeBrowsingSubresourceFilter');
addOrRemoveSettingWithFlag(
settings.ContentSettingsTypes.PAYMENT_HANDLER,
'enablePaymentHandlerContentSetting');
addOrRemoveSettingWithFlag(
- settings.ContentSettingsTypes.BLUETOOTH_SCANNING,
- 'enableBluetoothScanningContentSetting');
- addOrRemoveSettingWithFlag(
settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE,
'enableNativeFileSystemWriteContentSetting');
+ addOrRemoveSettingWithFlag(
+ settings.ContentSettingsTypes.MIXEDSCRIPT,
+ 'enableInsecureContentContentSetting');
return this.contentTypes_.slice(0);
},
diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
index 267e480c034..2b826c3b5a2 100644
--- a/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
+++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
@@ -14,8 +14,16 @@
* @enum {string}
*/
const ContentSettingProvider = {
+ POLICY: 'policy',
+ SUPERVISED_USER: 'supervised_user',
EXTENSION: 'extension',
+ INSTALLED_WEBAPP_PROVIDER: 'installed_webapp_provider',
+ NOTIFICATION_ANDROID: 'notification_android',
+ EPHEMERAL: 'ephemeral',
PREFERENCE: 'preference',
+ DEFAULT: 'default',
+ TESTS: 'tests',
+ TESTS_OTHER: 'tests_other'
};
/**
@@ -426,12 +434,9 @@ cr.define('settings', function() {
/** @override */
setCategoryPermissionForPattern(
primaryPattern, secondaryPattern, contentType, value, incognito) {
- // TODO(dschuyler): It may be incorrect for JS to send the embeddingOrigin
- // pattern. Look into removing this parameter from site_settings_handler.
- // Ignoring the |secondaryPattern| and using '' instead is a quick-fix.
chrome.send(
'setCategoryPermissionForPattern',
- [primaryPattern, '', contentType, value, incognito]);
+ [primaryPattern, secondaryPattern, contentType, value, incognito]);
}
/** @override */
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 a2adc7f829b..3db16d2d4f1 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
@@ -247,7 +247,16 @@
'$i18nPolymer{siteSettingsPaymentHandlerBlock}')]]"></cr-link-row>
</template>
- <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]">
+ <template is="dom-if" if="[[enableInsecureContentContentSetting_]]">
+ <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_MIXEDSCRIPT"
+ label="$i18n{siteSettingsInsecureContent}"
+ on-click="onTapNavigate_"
+ start-icon="settings:insecure-content"
+ sub-label="$i18n{siteSettingsInsecureContentBlock}"
+ </cr-link-row>
+ </template>
+
+ <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]">
<cr-link-row class="hr two-line"
data-route="SITE_SETTINGS_BLUETOOTH_SCANNING"
id="bluetooth-scanning" label="$i18n{siteSettingsBluetoothScanning}"
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 25bee399e1c..588b6d078aa 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
@@ -60,10 +60,10 @@ Polymer({
},
/** @private */
- enableBluetoothScanningContentSetting_: {
+ enableInsecureContentContentSetting_: {
type: Boolean,
value: function() {
- return loadTimeData.getBoolean('enableBluetoothScanningContentSetting');
+ return loadTimeData.getBoolean('enableInsecureContentContentSetting');
}
},
@@ -130,7 +130,7 @@ Polymer({
pairs.push([R.SITE_SETTINGS_SERIAL_PORTS, 'serial-ports']);
}
- if (this.enableBluetoothScanningContentSetting_) {
+ if (this.enableExperimentalWebPlatformFeatures_) {
pairs.push([R.SITE_SETTINGS_BLUETOOTH_SCANNING, 'bluetooth-scanning']);
}
@@ -140,6 +140,10 @@ Polymer({
]);
}
+ if (this.enableInsecureContentContentSetting_) {
+ pairs.push([R.SITE_SETTINGS_MIXEDSCRIPT, 'mixed-script']);
+ }
+
pairs.forEach(([route, id]) => {
this.focusConfig.set(route.path, () => this.async(() => {
cr.ui.focusWithoutInk(assert(this.$$(`#${id}`)));
diff --git a/chromium/chrome/browser/resources/signin/BUILD.gn b/chromium/chrome/browser/resources/signin/BUILD.gn
new file mode 100644
index 00000000000..0dbc17e4c9c
--- /dev/null
+++ b/chromium/chrome/browser/resources/signin/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("//tools/polymer/polymer.gni")
+
+group("polymer3_elements") {
+ deps = [
+ ":signin_shared_css_module",
+ "sync_confirmation:polymer3_elements",
+ ]
+}
+
+polymer_modulizer("signin_shared_css") {
+ html_file = "signin_shared_css.html"
+ js_file = "signin_shared_css.js"
+ html_type = "v3-ready"
+}
diff --git a/chromium/chrome/browser/resources/signin/signin_email_confirmation/signin_email_confirmation.html b/chromium/chrome/browser/resources/signin/signin_email_confirmation/signin_email_confirmation.html
index b0ce42afce4..2cb6a34e89b 100644
--- a/chromium/chrome/browser/resources/signin/signin_email_confirmation/signin_email_confirmation.html
+++ b/chromium/chrome/browser/resources/signin/signin_email_confirmation/signin_email_confirmation.html
@@ -7,7 +7,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
- <link rel="import" href="signin_shared_css.html">
+ <link rel="import" href="signin_shared_old_css.html">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/html/load_time_data.html">
diff --git a/chromium/chrome/browser/resources/signin/signin_error/signin_error.html b/chromium/chrome/browser/resources/signin/signin_error/signin_error.html
index 8510d635a75..251e1fa5b6d 100644
--- a/chromium/chrome/browser/resources/signin/signin_error/signin_error.html
+++ b/chromium/chrome/browser/resources/signin/signin_error/signin_error.html
@@ -5,13 +5,18 @@
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
- <link rel="import" href="signin_shared_css.html">
+ <link rel="import" href="signin_shared_old_css.html">
+ <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/html/load_time_data.html">
<link rel="import" href="chrome://resources/html/util.html">
<custom-style>
<style include="signin-dialog-shared">
+ html {
+ background: var(--md-background-color);
+ }
+
.details {
line-height: 20px;
margin-bottom: 8px;
diff --git a/chromium/chrome/browser/resources/signin/signin_shared_css.html b/chromium/chrome/browser/resources/signin/signin_shared_css.html
index 8267ae51398..79227224ba7 100644
--- a/chromium/chrome/browser/resources/signin/signin_shared_css.html
+++ b/chromium/chrome/browser/resources/signin/signin_shared_css.html
@@ -1,45 +1,41 @@
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-
<!-- Common styles for signin-related tab modal dialogs. -->
-<dom-module id="signin-dialog-shared">
- <template>
- <style>
- a {
- color: var(--cr-link-color);
- text-decoration: none;
- }
+<template>
+ <style>
+ a {
+ color: var(--cr-link-color);
+ text-decoration: none;
+ }
- body {
- margin: 0;
- padding: 0;
- }
+ body {
+ margin: 0;
+ padding: 0;
+ }
- .container {
- color: var(--cr-primary-text-color);
- width: 448px;
- }
+ .container {
+ color: var(--cr-primary-text-color);
+ width: 448px;
+ }
- .top-title-bar {
- align-items: center;
- border-bottom: var(--cr-separator-line);
- display: flex;
- font-size: 16px;
- height: 52px;
- padding: 0 24px;
- }
+ .top-title-bar {
+ align-items: center;
+ border-bottom: var(--cr-separator-line);
+ display: flex;
+ font-size: 16px;
+ height: 52px;
+ padding: 0 24px;
+ }
- .action-container {
- display: flex;
- justify-content: flex-end;
- padding: 16px;
- }
+ .action-container {
+ display: flex;
+ justify-content: flex-end;
+ padding: 16px;
+ }
<if expr="is_macosx or is_linux">
- .action-container {
- flex-flow: row-reverse;
- justify-content: flex-start;
- }
+ .action-container {
+ flex-flow: row-reverse;
+ justify-content: flex-start;
+ }
</if>
- </style>
- </template>
-</dom-module>
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/signin/signin_shared_css.js b/chromium/chrome/browser/resources/signin/signin_shared_css.js
new file mode 100644
index 00000000000..ce2743cab1f
--- /dev/null
+++ b/chromium/chrome/browser/resources/signin/signin_shared_css.js
@@ -0,0 +1,11 @@
+/* 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 'chrome://resources/cr_elements/shared_vars_css.m.js';
+
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.setAttribute('assetpath', 'chrome://resources/');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('signin-dialog-shared');
diff --git a/chromium/chrome/browser/resources/signin/signin_shared_old_css.html b/chromium/chrome/browser/resources/signin/signin_shared_old_css.html
new file mode 100644
index 00000000000..8267ae51398
--- /dev/null
+++ b/chromium/chrome/browser/resources/signin/signin_shared_old_css.html
@@ -0,0 +1,45 @@
+<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
+
+<!-- Common styles for signin-related tab modal dialogs. -->
+<dom-module id="signin-dialog-shared">
+ <template>
+ <style>
+ a {
+ color: var(--cr-link-color);
+ text-decoration: none;
+ }
+
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ .container {
+ color: var(--cr-primary-text-color);
+ width: 448px;
+ }
+
+ .top-title-bar {
+ align-items: center;
+ border-bottom: var(--cr-separator-line);
+ display: flex;
+ font-size: 16px;
+ height: 52px;
+ padding: 0 24px;
+ }
+
+ .action-container {
+ display: flex;
+ justify-content: flex-end;
+ padding: 16px;
+ }
+
+<if expr="is_macosx or is_linux">
+ .action-container {
+ flex-flow: row-reverse;
+ justify-content: flex-start;
+ }
+</if>
+ </style>
+ </template>
+</dom-module>
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/BUILD.gn b/chromium/chrome/browser/resources/signin/sync_confirmation/BUILD.gn
index 6f36b5e3c54..4492e543319 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/BUILD.gn
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/BUILD.gn
@@ -3,8 +3,23 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
-js_type_check("closure_compile") {
+group("closure_compile") {
+ deps = [
+ ":closure_compile_polymer2",
+ ":closure_compile_polymer3",
+ ]
+}
+
+js_type_check("closure_compile_polymer2") {
+ deps = [
+ ":sync_disabled_confirmation",
+ ]
+}
+
+js_type_check("closure_compile_polymer3") {
+ is_polymer3 = true
deps = [
":sync_confirmation",
":sync_confirmation_app",
@@ -15,25 +30,46 @@ js_type_check("closure_compile") {
js_library("sync_confirmation") {
deps = [
":sync_confirmation_browser_proxy",
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
}
js_library("sync_confirmation_app") {
deps = [
":sync_confirmation_browser_proxy",
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:web_ui_listener_behavior",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:assert.m",
+ "//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
js_library("sync_confirmation_browser_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [
"$externs_path/chrome_send.js",
"$externs_path/metrics_private.js",
]
}
+
+js_library("sync_disabled_confirmation") {
+ deps = [
+ "//ui/webui/resources/js:assert",
+ "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:util",
+ ]
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":sync_confirmation_app_module",
+ ]
+}
+
+polymer_modulizer("sync_confirmation_app") {
+ html_file = "sync_confirmation_app.html"
+ js_file = "sync_confirmation_app.js"
+ html_type = "v3-ready"
+}
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html
index 52d93830335..328bfda7c42 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
- <link rel="import" href="sync_confirmation_app.html"></link>
+ <script type="module" src="sync_confirmation_app.js"></script>
<style>
body {
margin: 0;
@@ -21,7 +21,5 @@
<sync-confirmation-app></sync-confirmation-app>
</body>
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
- <link rel="import" href="chrome://resources/html/cr.html"></script>
- <link rel="import" href="chrome://resources/html/util.html"></script>
- <script src="sync_confirmation.js"></script>
+ <script type="module" src="sync_confirmation.js"></script>
</html>
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
index 31aa325f3ef..04c560fac17 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation.js
@@ -2,31 +2,27 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-cr.define('sync.confirmation', function() {
- 'use strict';
+import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
- function initialize() {
- const syncConfirmationBrowserProxy =
- sync.confirmation.SyncConfirmationBrowserProxyImpl.getInstance();
- // Prefer using |document.body.offsetHeight| instead of
- // |document.body.scrollHeight| as it returns the correct height of the
- // even when the page zoom in Chrome is different than 100%.
- syncConfirmationBrowserProxy.initializedWithSize(
- [document.body.offsetHeight]);
- // The web dialog size has been initialized, so reset the body width to
- // auto. This makes sure that the body only takes up the viewable width,
- // e.g. when there is a scrollbar.
- document.body.style.width = 'auto';
- }
+import {SyncConfirmationBrowserProxyImpl} from './sync_confirmation_browser_proxy.js';
- function clearFocus() {
- document.activeElement.blur();
- }
+function initialize() {
+ addWebUIListener('clear-focus', clearFocus);
+ const syncConfirmationBrowserProxy =
+ SyncConfirmationBrowserProxyImpl.getInstance();
+ // Prefer using |document.body.offsetHeight| instead of
+ // |document.body.scrollHeight| as it returns the correct height of the
+ // even when the page zoom in Chrome is different than 100%.
+ syncConfirmationBrowserProxy.initializedWithSize(
+ [document.body.offsetHeight]);
+ // The web dialog size has been initialized, so reset the body width to
+ // auto. This makes sure that the body only takes up the viewable width,
+ // e.g. when there is a scrollbar.
+ document.body.style.width = 'auto';
+}
- return {
- clearFocus: clearFocus,
- initialize: initialize,
- };
-});
+function clearFocus() {
+ document.activeElement.blur();
+}
-document.addEventListener('DOMContentLoaded', sync.confirmation.initialize);
+document.addEventListener('DOMContentLoaded', initialize);
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.html b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.html
index fffc18a7d60..818fad1c1fc 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.html
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.html
@@ -1,169 +1,152 @@
-<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/html/cr.html">
-<link rel="import" href="chrome://resources/html/load_time_data.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="signin_shared_css.html">
-<link rel="import" href="sync_confirmation_browser_proxy.html">
-
-<script src="chrome://sync-confirmation/strings.js"></script>
-
-<dom-module id="sync-confirmation-app">
- <template>
- <style include="signin-dialog-shared">
- :host {
- color: var(--cr-primary-text-color);
- display: block;
- }
-
- cr-button {
- padding-inline-end: 16px;
- padding-inline-start: 16px;
- }
-
- .action-container {
- bottom: 0;
- box-sizing: border-box;
- position: absolute;
- width: 100%;
- }
-
- cr-button:not(.action-button) {
- margin-inline-start: 8px;
- }
+<style include="signin-dialog-shared">
+ :host {
+ color: var(--cr-primary-text-color);
+ display: block;
+ }
+
+ cr-button {
+ padding-inline-end: 16px;
+ padding-inline-start: 16px;
+ }
+
+ .action-container {
+ bottom: 0;
+ box-sizing: border-box;
+ position: absolute;
+ width: 100%;
+ }
+
+ cr-button:not(.action-button) {
+ margin-inline-start: 8px;
+ }
<if expr="is_macosx or is_linux">
- /* This works together with the button-flip in signin-dialog-shared. */
- cr-button:not(.action-button) {
- margin-inline-end: 8px;
- margin-inline-start: 0;
- }
+ /* This works together with the button-flip in signin-dialog-shared. */
+ cr-button:not(.action-button) {
+ margin-inline-end: 8px;
+ margin-inline-start: 0;
+ }
</if>
- #illustration-container {
- height: 168px;
- margin-bottom: 32px;
- position: relative;
- width: 100%;
- }
-
- #illustration {
- background: url(./images/sync_confirmation_illustration.svg);
- background-size: 100% 100%;
- height: 100%;
- position: absolute;
- top: 0;
- width: 100%;
- }
-
- @media (prefers-color-scheme: dark) {
- #illustration {
- background-image:
- url(./images/sync_confirmation_illustration_dark.svg);
- }
- }
-
- #illustration-container > img {
- border-radius: 50%;
- height: 68px;
- left: 0;
- margin: auto;
- position: absolute;
- right: 0;
- top: 96px;
- width: 68px;
- }
-
- .heading {
- font-weight: normal;
- margin-bottom: 32px;
- padding: 0 24px;
- text-align: center;
- }
-
- #content-container {
- /* Saves space for button row. */
- padding-bottom: 96px;
- position: relative;
- width: 100%;
- }
-
- .message-container {
- line-height: 20px;
- margin-bottom: 16px;
- padding: 0 24px;
- }
-
- .secondary {
- color: var(--cr-secondary-text-color);
- }
-
- @media (prefers-color-scheme: light) {
- #grey-banner {
- background: var(--paper-grey-50);
- height: 128px;
- top: 0;
- width: 100%;
- }
- }
-
- #footer {
- margin-bottom: 0;
- padding-top: 12px;
- }
-
- #settingsButton {
- left: 16px;
- position: absolute;
- }
-
- :host-context([dir='rtl']) #settingsButton {
- left: auto;
- right: 16px;
- }
- </style>
-
- <!--
- Use the 'consent-description' attribute to annotate all the UI elements
- that are part of the text the user reads before consenting to the Sync
- data collection . Similarly, use 'consent-confirmation' on UI elements on
- which user clicks to indicate consent.
- -->
-
- <div id="illustration-container">
- <div id="grey-banner"></div>
- <div id="illustration"></div>
- <img src="[[accountImageSrc_]]">
+ #illustration-container {
+ height: 168px;
+ margin-bottom: 32px;
+ position: relative;
+ width: 100%;
+ }
+
+ #illustration {
+ background: url(./images/sync_confirmation_illustration.svg);
+ background-size: 100% 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ #illustration {
+ background-image:
+ url(./images/sync_confirmation_illustration_dark.svg);
+ }
+ }
+
+ #illustration-container > img {
+ border-radius: 50%;
+ height: 68px;
+ left: 0;
+ margin: auto;
+ position: absolute;
+ right: 0;
+ top: 96px;
+ width: 68px;
+ }
+
+ .heading {
+ font-weight: normal;
+ margin-bottom: 32px;
+ padding: 0 24px;
+ text-align: center;
+ }
+
+ #content-container {
+ /* Saves space for button row. */
+ padding-bottom: 96px;
+ position: relative;
+ width: 100%;
+ }
+
+ .message-container {
+ line-height: 20px;
+ margin-bottom: 16px;
+ padding: 0 24px;
+ }
+
+ .secondary {
+ color: var(--cr-secondary-text-color);
+ }
+
+ @media (prefers-color-scheme: light) {
+ #grey-banner {
+ background: var(--paper-grey-50);
+ height: 128px;
+ top: 0;
+ width: 100%;
+ }
+ }
+
+ #footer {
+ margin-bottom: 0;
+ padding-top: 12px;
+ }
+
+ #settingsButton {
+ left: 16px;
+ position: absolute;
+ }
+
+ :host-context([dir='rtl']) #settingsButton {
+ left: auto;
+ right: 16px;
+ }
+</style>
+
+<!--
+ Use the 'consent-description' attribute to annotate all the UI elements
+ that are part of the text the user reads before consenting to the Sync
+ data collection . Similarly, use 'consent-confirmation' on UI elements on
+ which user clicks to indicate consent.
+-->
+
+<div id="illustration-container">
+ <div id="grey-banner"></div>
+ <div id="illustration"></div>
+ <img src="[[accountImageSrc_]]">
+</div>
+<div id="content-container">
+ <h1 id="syncConfirmationHeading" class="heading" consent-description>
+ $i18n{syncConfirmationTitle}
+ </h1>
+ <div class="message-container">
+ <div consent-description>$i18n{syncConfirmationSyncInfoTitle}</div>
+ <div class="secondary" consent-description>
+ $i18n{syncConfirmationSyncInfoDesc}
</div>
- <div id="content-container">
- <h1 id="syncConfirmationHeading" class="heading" consent-description>
- $i18n{syncConfirmationTitle}
- </h1>
- <div class="message-container">
- <div consent-description>$i18n{syncConfirmationSyncInfoTitle}</div>
- <div class="secondary" consent-description>
- $i18n{syncConfirmationSyncInfoDesc}
- </div>
- </div>
- <div id="footer" class="message-container secondary">
- $i18n{syncConfirmationSettingsInfo}
- </div>
- <div class="action-container">
- <cr-button class="action-button" id="confirmButton"
- on-click="onConfirm_" consent-confirmation>
- $i18n{syncConfirmationConfirmLabel}
- </cr-button>
- <cr-button on-click="onUndo_">
- $i18n{syncConfirmationUndoLabel}
- </cr-button>
- <cr-button id="settingsButton" on-click="onGoToSettings_"
- consent-confirmation>
- $i18n{syncConfirmationSettingsLabel}
- </cr-button>
- </div>
- </div>
- </template>
- <script src="sync_confirmation_app.js"></script>
-</dom-module>
+ </div>
+ <div id="footer" class="message-container secondary">
+ $i18n{syncConfirmationSettingsInfo}
+ </div>
+ <div class="action-container">
+ <cr-button class="action-button" id="confirmButton"
+ on-click="onConfirm_" consent-confirmation>
+ $i18n{syncConfirmationConfirmLabel}
+ </cr-button>
+ <cr-button on-click="onUndo_">
+ $i18n{syncConfirmationUndoLabel}
+ </cr-button>
+ <cr-button id="settingsButton" on-click="onGoToSettings_"
+ consent-confirmation>
+ $i18n{syncConfirmationSettingsLabel}
+ </cr-button>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.js b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.js
index 57f29b847a5..2e9c4aa7af8 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.js
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.js
@@ -2,9 +2,23 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
+import './strings.m.js';
+import './signin_shared_css.js';
+
+import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {SyncConfirmationBrowserProxy, SyncConfirmationBrowserProxyImpl} from './sync_confirmation_browser_proxy.js';
+
Polymer({
is: 'sync-confirmation-app',
+ _template: html`{__html_template__}`,
+
behaviors: [
WebUIListenerBehavior,
],
@@ -19,7 +33,7 @@ Polymer({
},
},
- /** @private {?sync.confirmation.SyncConfirmationBrowserProxy} */
+ /** @private {?SyncConfirmationBrowserProxy} */
syncConfirmationBrowserProxy_: null,
/** @private {?function(Event)} */
@@ -28,7 +42,7 @@ Polymer({
/** @override */
attached: function() {
this.syncConfirmationBrowserProxy_ =
- sync.confirmation.SyncConfirmationBrowserProxyImpl.getInstance();
+ SyncConfirmationBrowserProxyImpl.getInstance();
this.boundKeyDownHandler_ = this.onKeyDown_.bind(this);
// This needs to be bound to document instead of "this" because the dialog
// window opens initially, the focus level is only on document, so the key
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.html b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.html
deleted file mode 100644
index 636a6b9e214..00000000000
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="sync_confirmation_browser_proxy.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js
index c5cb104af72..b98c5ee1fe9 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js
@@ -6,75 +6,69 @@
* @fileoverview A helper object used by the sync confirmation dialog to
* interact with the browser.
*/
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
-cr.define('sync.confirmation', function() {
- /** @interface */
- class SyncConfirmationBrowserProxy {
- /**
- * Called when the user confirms the Sync Confirmation dialog.
- * @param {!Array<string>} description Strings that the user was presented
- * with in the UI.
- * @param {string} confirmation Text of the element that the user
- * clicked on.
- */
- confirm(description, confirmation) {}
+/** @interface */
+export class SyncConfirmationBrowserProxy {
+ /**
+ * Called when the user confirms the Sync Confirmation dialog.
+ * @param {!Array<string>} description Strings that the user was presented
+ * with in the UI.
+ * @param {string} confirmation Text of the element that the user
+ * clicked on.
+ */
+ confirm(description, confirmation) {}
- /**
- * Called when the user undoes the Sync confirmation.
- */
- undo() {}
+ /**
+ * Called when the user undoes the Sync confirmation.
+ */
+ undo() {}
- /**
- * Called when the user clicks on the Settings link in
- * the Sync Confirmation dialog.
- * @param {!Array<string>} description Strings that the user was presented
- * with in the UI.
- * @param {string} confirmation Text of the element that the user
- * clicked on.
- */
- goToSettings(description, confirmation) {}
+ /**
+ * Called when the user clicks on the Settings link in
+ * the Sync Confirmation dialog.
+ * @param {!Array<string>} description Strings that the user was presented
+ * with in the UI.
+ * @param {string} confirmation Text of the element that the user
+ * clicked on.
+ */
+ goToSettings(description, confirmation) {}
- /** @param {!Array<number>} height */
- initializedWithSize(height) {}
+ /** @param {!Array<number>} height */
+ initializedWithSize(height) {}
- /**
- * Called when the WebUIListener for "account-image-changed" was added.
- */
- requestAccountImage() {}
- }
-
- /** @implements {sync.confirmation.SyncConfirmationBrowserProxy} */
- class SyncConfirmationBrowserProxyImpl {
- /** @override */
- confirm(description, confirmation) {
- chrome.send('confirm', [description, confirmation]);
- }
+ /**
+ * Called when the WebUIListener for "account-image-changed" was added.
+ */
+ requestAccountImage() {}
+}
- /** @override */
- undo() {
- chrome.send('undo');
- }
+/** @implements {SyncConfirmationBrowserProxy} */
+export class SyncConfirmationBrowserProxyImpl {
+ /** @override */
+ confirm(description, confirmation) {
+ chrome.send('confirm', [description, confirmation]);
+ }
- /** @override */
- goToSettings(description, confirmation) {
- chrome.send('goToSettings', [description, confirmation]);
- }
+ /** @override */
+ undo() {
+ chrome.send('undo');
+ }
- /** @override */
- initializedWithSize(height) {
- chrome.send('initializedWithSize', height);
- }
+ /** @override */
+ goToSettings(description, confirmation) {
+ chrome.send('goToSettings', [description, confirmation]);
+ }
- /** @override */
- requestAccountImage() {
- chrome.send('accountImageRequest');
- }
+ /** @override */
+ initializedWithSize(height) {
+ chrome.send('initializedWithSize', height);
}
- cr.addSingletonGetter(SyncConfirmationBrowserProxyImpl);
+ /** @override */
+ requestAccountImage() {
+ chrome.send('accountImageRequest');
+ }
+}
- return {
- SyncConfirmationBrowserProxy: SyncConfirmationBrowserProxy,
- SyncConfirmationBrowserProxyImpl: SyncConfirmationBrowserProxyImpl,
- };
-});
+addSingletonGetter(SyncConfirmationBrowserProxyImpl);
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html
index 74e05238e9e..059bc92e3b9 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.html
@@ -8,11 +8,10 @@
background-color: var(--md-background-color);
}
</style>
- </custom-style>
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
- <link rel="import" href="signin_shared_css.html">
+ <link rel="import" href="signin_shared_old_css.html">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<custom-style>
<style include="signin-dialog-shared">
diff --git a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.js b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.js
index 12307c5704b..97f494ac9b6 100644
--- a/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.js
+++ b/chromium/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation.js
@@ -43,6 +43,7 @@ cr.define('sync.confirmation', function() {
}
function initialize() {
+ cr.addWebUIListener('clear-focus', clearFocus);
document.addEventListener('keydown', onKeyDown);
$('confirmButton').addEventListener('click', onConfirm);
$('undoButton').addEventListener('click', onUndo);
@@ -67,11 +68,7 @@ cr.define('sync.confirmation', function() {
}
}
- // TODO(tangltom): clearFocus is called directly by the C++ handler.
- // C++ handlers should not be calling JS functions by name anymore. They
- // should be firing events with FireWebuiListener and have the page itself
- // decide whether to listen or not listen to the event.
- return {clearFocus: clearFocus, initialize: initialize};
+ return {initialize: initialize};
});
document.addEventListener('DOMContentLoaded', sync.confirmation.initialize);
diff --git a/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp b/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp
index efdd213ea9f..b54e9e755cf 100644
--- a/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp
+++ b/chromium/chrome/browser/resources/supervised_user_error_page_resources.grdp
@@ -1,4 +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" />
+ <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" compress="brotli" />
</grit-part>
diff --git a/chromium/chrome/browser/resources/tab_strip/BUILD.gn b/chromium/chrome/browser/resources/tab_strip/BUILD.gn
index ece86c1ad36..f6b804866d5 100644
--- a/chromium/chrome/browser/resources/tab_strip/BUILD.gn
+++ b/chromium/chrome/browser/resources/tab_strip/BUILD.gn
@@ -7,13 +7,18 @@ import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
deps = [
+ ":alert_indicator",
":custom_element",
":tab",
":tab_list",
+ ":tab_strip_embedder_proxy",
":tabs_api_proxy",
]
}
+js_library("alert_indicator") {
+}
+
js_library("custom_element") {
}
@@ -28,26 +33,31 @@ 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") {
+js_library("tab_strip_embedder_proxy") {
+ deps = [
+ "//ui/webui/resources/js:cr.m",
+ ]
}
group("tab_strip_modules") {
deps = [
+ ":alert_indicator_module",
":tab_list_module",
":tab_module",
]
}
+polymer_modulizer("alert_indicator") {
+ js_file = "alert_indicator.js"
+ html_file = "alert_indicator.html"
+ html_type = "v3-ready"
+}
+
polymer_modulizer("tab") {
js_file = "tab.js"
html_file = "tab.html"
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicator.html b/chromium/chrome/browser/resources/tab_strip/alert_indicator.html
new file mode 100644
index 00000000000..5a4e4c7481c
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicator.html
@@ -0,0 +1,77 @@
+<style>
+ @keyframes fade-in {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+ }
+
+ @keyframes fade-out {
+ 0% { opacity: 1; }
+ 100% { opacity: 0; }
+ }
+
+ :host {
+ -webkit-mask: center / contain no-repeat;
+ animation: fade-in 200ms ease-in forwards;
+ background-color: currentColor;
+ display: block;
+ height: 100%;
+ opacity: 0;
+ width: 16px;
+ }
+
+ :host([fade-out]) {
+ animation: fade-out 1000ms ease-in;
+ }
+
+ :host([alert-state='pip']) {
+ -webkit-mask-image: url(alert_indicators/picture_in_picture_alt.svg);
+ background-color: var(--tabstrip-indicator-pip-color);
+ }
+
+ :host([alert-state='serial']) {
+ -webkit-mask-image: url(alert_indicators/serial_port.svg);
+ }
+
+ :host([alert-state='muted']) {
+ -webkit-mask-image: url(alert_indicators/tab_audio_muting_rounded.svg);
+ }
+
+ :host([alert-state='audio']) {
+ -webkit-mask-image: url(alert_indicators/tab_audio_rounded.svg);
+ }
+
+ :host([alert-state='bluetooth']) {
+ -webkit-mask-image: url(alert_indicators/tab_bluetooth_connected.svg);
+ }
+
+ :host([alert-state='capturing']) {
+ -webkit-mask-image:
+ url(alert_indicators/tab_media_capturing_with_arrow.svg);
+ background-color: var(--tabstrip-indicator-capturing-color);
+ }
+
+ :host([alert-state='recording']) {
+ -webkit-mask-image: url(alert_indicators/tab_media_recording.svg);
+ background-color: var(--tabstrip-indicator-recording-color);
+ }
+
+ :host([alert-state='usb']) {
+ -webkit-mask-image: url(alert_indicators/tab_usb_connected.svg);
+ -webkit-mask-size: 20px;
+ }
+
+ :host([alert-state='vr']) {
+ -webkit-mask-image: url(alert_indicators/vr_headset.svg);
+ }
+
+ :host([alert-state='capturing']),
+ :host([alert-state='recording']) {
+ animation:
+ fade-in 200ms ease-in 0,
+ fade-out 1000ms ease-in 200ms,
+ fade-in 200ms ease-in 1200s,
+ fade-out 1000ms ease-in 1400ms,
+ fade-in 200ms ease-in 2400ms;
+ animation-fill-mode: forwards;
+ }
+</style>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicator.js b/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
new file mode 100644
index 00000000000..2d41eab42f6
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicator.js
@@ -0,0 +1,19 @@
+// 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 {CustomElement} from './custom_element.js';
+
+export class AlertIndicatorElement extends CustomElement {
+ static get template() {
+ return `{__html_template__}`;
+ }
+
+ /** @override */
+ remove() {
+ this.toggleAttribute('fade-out', true);
+ this.addEventListener('animationend', () => super.remove(), {once: true});
+ }
+}
+
+customElements.define('tabstrip-alert-indicator', AlertIndicatorElement);
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/picture_in_picture_alt.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/picture_in_picture_alt.svg
new file mode 100644
index 00000000000..7ef00c31419
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/picture_in_picture_alt.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M 16 14 H 0 V 2 h 16 v 12 Z M 1 13 h 14 V 3 H 1 v 10 Z M 8 8 h 6 v 4 H 8 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/serial_port.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/serial_port.svg
new file mode 100644
index 00000000000..1bf89c75d27
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/serial_port.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M 22 9 V 7 h -2 V 5 c 0 -1.1 -0.9 -2 -2 -2 H 4 c -1.1 0 -2 0.9 -2 2 v 14 c 0 1.1 0.9 2 2 2 h 14 c 1.1 0 2 -0.9 2 -2 v -2 h 2 v -2 h -2 v -2 h 2 v -2 h -2 V 9 h 2 Z m -4 10 H 4 V 5 h 14 v 14 Z M 6 13 h 5 v 4 H 6 Z m 6 -6 h 4 v 3 h -4 Z M 6 7 h 5 v 5 H 6 Z m 6 4 h 4 v 6 h -4 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_muting_rounded.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_muting_rounded.svg
new file mode 100644
index 00000000000..3da0244cbe4
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_muting_rounded.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M 8.5 6 C 8.5 5.02 7.93 4.17 7.11 3.76 L 7.11 4.99 L 8.47 6.35 C 8.49 6.24 8.5 6.12 8.5 6 Z M 9.89 6 C 9.89 6.52 9.78 7.01 9.59 7.47 L 10.43 8.31 C 10.79 7.62 11 6.83 11 6 C 11 3.62 9.34 1.63 7.11 1.13 L 7.11 2.27 C 8.72 2.75 9.89 4.24 9.89 6 Z M 1.71 1 L 1 1.71 L 3.63 4.33 L 1 4.33 L 1 7.67 L 3.22 7.67 L 6 10.44 L 6 6.71 L 8.36 9.07 C 7.99 9.36 7.57 9.58 7.11 9.72 L 7.11 10.87 C 7.88 10.69 8.57 10.34 9.16 9.86 L 10.29 11 L 11 10.29 L 6 5.29 L 1.71 1 Z M 6 1.56 L 4.84 2.72 L 6 3.88 L 6 1.56 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_rounded.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_rounded.svg
new file mode 100644
index 00000000000..a09790ea5ed
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_audio_rounded.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path d="M 1 4.29 L 1 7.71 L 3.22 7.71 L 6 10.56 L 6 1.44 L 3.22 4.29 L 1 4.29 Z M 8.5 6 C 8.5 4.99 7.93 4.12 7.11 3.7 L 7.11 8.29 C 7.93 7.88 8.5 7.01 8.5 6 Z M 7.11 1 L 7.11 2.17 C 8.72 2.66 9.89 4.19 9.89 6 C 9.89 7.81 8.72 9.34 7.11 9.83 L 7.11 11 C 9.34 10.48 11 8.44 11 6 C 11 3.56 9.34 1.52 7.11 1 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_bluetooth_connected.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_bluetooth_connected.svg
new file mode 100644
index 00000000000..7b55099bb99
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_bluetooth_connected.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M 16.8 2 h -1.4 v 10.63 L 8.97 6.2 L 7 8.17 L 14.83 16 L 7 23.83 L 8.97 25.8 l 6.43 -6.43 V 30 h 1.4 l 7.99 -7.99 L 18.77 16 l 6.02 -6.01 L 16.8 2 Z M 18 7 l 3 3 l -3 3 l 0.2 -5.64 L 18 7 Z m 3 15.01 L 18 25 v -6 l 2.83 3.01 H 21 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_capturing_with_arrow.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_capturing_with_arrow.svg
new file mode 100644
index 00000000000..55d264b73a5
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_capturing_with_arrow.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M 0 2 L 16 2 L 16 14 L 0 14 L 0 2 Z M 1 3 L 1 13 L 15 13 L 15 3 L 1 3 Z M 2 4 L 14 4 L 14 12 L 2 12 L 2 4 Z M 7.92 9 L 7.92 11 L 11.5 8 L 7.92 5 L 7.92 7 C 5.14 7 4.38 9 4 11 C 4.93 9.6 5.88 8.96 7.92 9 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_recording.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_recording.svg
new file mode 100644
index 00000000000..d9ffeafa73a
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_media_recording.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill-rule="evenodd"><path d="M 16 28 c 6.63 0 12 -5.37 12 -12 C 28 9.37 22.63 4 16 4 C 9.37 4 4 9.37 4 16 c 0 6.63 5.37 12 12 12 Z m 0 -2 c 5.52 0 10 -4.48 10 -10 C 26 10.48 21.52 6 16 6 C 10.48 6 6 10.48 6 16 c 0 5.52 4.48 10 10 10 Z m 0 -2 c 4.42 0 8 -3.58 8 -8 c 0 -4.42 -3.58 -8 -8 -8 c -4.42 0 -8 3.58 -8 8 c 0 4.42 3.58 8 8 8 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_usb_connected.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_usb_connected.svg
new file mode 100644
index 00000000000..c378a79e433
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/tab_usb_connected.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M 19 16 h 1 v 2 h -3 v -8 h 2 l -3 -4 l -3 4 h 2 v 8 h -3 v -2 c 0.85 -0.53 1.34 -1.23 1 -2 c 0.34 -1.27 -0.64 -2.25 -2 -2 c -1.02 -0.25 -2 0.73 -2 2 c 0 0.77 0.49 1.47 1 2 v 2 c 0.18 0.99 1.06 1.87 2 2 h 3 v 3 c -0.59 0.26 -1.07 0.98 -1 2 c -0.07 1.03 0.91 2 2 2 c 1.29 0 2.27 -0.97 2 -2 c 0.27 -1.02 -0.21 -1.74 -1 -2 v -3 h 3 c 1.14 -0.13 2.01 -1.01 2 -2 v -2 h 1 v -4 h -4 v 4 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/alert_indicators/vr_headset.svg b/chromium/chrome/browser/resources/tab_strip/alert_indicators/vr_headset.svg
new file mode 100644
index 00000000000..47d8a07244e
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/alert_indicators/vr_headset.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M 17.4 5.57 A 2.12 2.12 0 0 0 15.94 5 H 4.06 c -0.55 0 -1.07 0.2 -1.46 0.56 c -0.39 0.37 -0.6 0.85 -0.6 1.36 v 6.14 c 0 0.52 0.21 1 0.6 1.36 c 0.39 0.37 0.91 0.56 1.46 0.56 h 2.85 c 0.37 0 0.74 -0.09 1.06 -0.28 c 0.32 -0.18 0.58 -0.43 0.76 -0.74 l 0.81 -1.4 a 0.48 0.48 0 0 1 0.13 -0.62 a 0.56 0.56 0 0 1 0.67 0 c 0.2 0.15 0.25 0.41 0.13 0.62 l 0.81 1.4 c 0.18 0.3 0.44 0.56 0.76 0.74 c 0.32 0.18 0.68 0.28 1.06 0.28 h 2.85 c 0.55 0 1.07 -0.2 1.46 -0.56 c 0.39 -0.36 0.6 -0.85 0.6 -1.36 V 6.93 c 0 -0.51 -0.21 -1 -0.6 -1.36 Z M 6.5 11.5 c -1.11 0 -2 -0.9 -2 -2 c 0 -1.1 0.9 -2 2 -2 c 1.1 0 2 0.9 2 2 c 0 1.1 -0.89 2 -2 2 Z m 7 0 c -1.11 0 -2 -0.9 -2 -2 c 0 -1.1 0.9 -2 2 -2 c 1.1 0 2 0.9 2 2 c 0 1.1 -0.89 2 -2 2 Z" /></svg>
diff --git a/chromium/chrome/browser/resources/tab_strip/tab.html b/chromium/chrome/browser/resources/tab_strip/tab.html
index 1e715432804..85517760d2d 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab.html
+++ b/chromium/chrome/browser/resources/tab_strip/tab.html
@@ -1,38 +1,170 @@
<style>
:host {
- border-radius: var(--tabstrip-card-border-radius);
- box-shadow: var(--tabstrip-elevation-box-shadow);
+ --tabstrip-tab-title-height: 40px;
+ --tabstrip-tab-transition-duration: 250ms;
+
cursor: pointer;
+ height: var(--tabstrip-tab-height);
+ position: relative;
+ width: var(--tabstrip-tab-width);
+ }
+
+ #dragImage {
+ background: var(--tabstrip-tab-background-color);
+ border-radius: var(--tabstrip-tab-border-radius);
+ box-shadow: 0 0 0 1px var(--tabstrip-tab-separator-color);
+ color: var(--tabstrip-tab-text-color);
display: flex;
flex-direction: column;
- height: 230px;
+ height: 100%;
overflow: hidden;
- width: 280px;
+ width: 100%;
}
- :host([active]) {
- box-shadow: 0 0 0 2px var(--tabstrip-focus-color);
+ :host([active]) #dragImage {
+ box-shadow: 0 0 0 2px var(--tabstrip-tab-active-border-color);
outline: none;
}
#title {
align-items: center;
- background: var(--tabstrip-card-background-color);
- border-block-end: 1px solid var(--tabstrip-separator-color);
+ border-block-end: 1px solid var(--tabstrip-tab-separator-color);
box-sizing: border-box;
display: flex;
- height: 40px;
+ height: var(--tabstrip-tab-title-height);
justify-content: center;
margin: 0;
- padding-inline-end: 4px;
- padding-inline-start: 12px;
+ overflow: hidden;
}
- #favicon {
+ #faviconContainer {
+ --favicon-size: 16px;
flex-shrink: 0;
- height: 16px;
+ height: var(--favicon-size);
margin-inline-end: 8px;
- width: 16px;
+ margin-inline-start: 12px;
+ max-width: var(--favicon-size);
+ position: relative;
+ /* When transitioning to the default visible state, the margin and max-width
+ * transitions should finish first, then the opacity should be set to 1.
+ * This prevents the favicon and loading spinners from looking cropped
+ * while the element transitions. */
+ transition: margin var(--tabstrip-tab-transition-duration),
+ max-width var(--tabstrip-tab-transition-duration),
+ opacity 0ms linear var(--tabstrip-tab-transition-duration);
+ width: var(--favicon-size);
+ }
+
+ :host([hide-icon_]) #faviconContainer {
+ margin-inline-end: 0;
+ max-width: 0;
+ opacity: 0;
+ /* When transitioning to the hidden state, set opacity immediately to 0
+ * while transitioning the other values normally. */
+ transition: margin var(--tabstrip-tab-transition-duration),
+ max-width var(--tabstrip-tab-transition-duration),
+ opacity 0ms;
+ }
+
+ :host([pinned_]) #faviconContainer {
+ margin: 0;
+ }
+
+ #progressSpinner,
+ #favicon,
+ #crashedIcon {
+ height: var(--favicon-size);
+ left: 50%;
+ position: absolute;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: var(--favicon-size);
+ }
+
+ #progressSpinner {
+ -webkit-mask:
+ url(chrome://resources/images/throbber_small.svg)
+ center/contain no-repeat;
+ display: none;
+ }
+
+ #favicon {
+ background-size: contain;
+ transition: border-radius var(--tabstrip-tab-transition-duration);
+ }
+
+ #crashedIcon {
+ -webkit-mask:
+ url(chrome://theme/IDR_CRASH_SAD_FAVICON@2x)
+ center/contain no-repeat;
+ background-color: currentColor;
+ opacity: 0;
+ transform: translate(-50%, 100%);
+ }
+
+ #blocked {
+ background: var(--tabstrip-tab-blocked-color);
+ border: solid 1px var(--tabstrip-tab-background-color);
+ border-radius: 50%;
+ bottom: 0;
+ display: none;
+ height: 6px;
+ position: absolute;
+ right: 0;
+ transform: translate(50%, 50%);
+ width: 6px;
+ }
+
+ :host([waiting_]) #progressSpinner,
+ :host([loading_]) #progressSpinner {
+ display: block;
+ }
+
+ :host([loading_]) #favicon {
+ border-radius: 50%;
+ height: calc(var(--favicon-size) - 6px);
+ overflow: hidden;
+ width: calc(var(--favicon-size) - 6px);
+ }
+
+ :host([waiting_]) #progressSpinner {
+ background-color: var(--tabstrip-tab-waiting-spinning-color);
+ transform: /* Center first, then flip horizontally. */
+ translate(-50%, -50%) scaleX(-1);
+ }
+
+ :host([waiting_]) #favicon {
+ display: none;
+ }
+
+ :host([loading_]) #progressSpinner {
+ background-color: var(--tabstrip-tab-loading-spinning-color);
+ }
+
+ :host([crashed_]) #favicon {
+ opacity: 0;
+ transform: translate(-50%, 100%);
+ transition:
+ opacity var(--tabstrip-tab-transition-duration),
+ transform var(--tabstrip-tab-transition-duration);
+ }
+
+ :host([crashed_]) #crashedIcon {
+ opacity: 1;
+ transform: translate(-50%, -50%);
+ transition:
+ opacity var(--tabstrip-tab-transition-duration),
+ transform var(--tabstrip-tab-transition-duration);
+ /* Wait until transition for #favicon finishes. */
+ transition-delay: var(--tabstrip-tab-transition-duration);
+ }
+
+ :host([blocked_]) #blocked {
+ display: block;
+ }
+
+ :host([active][blocked_]) #blocked {
+ display: none;
}
#titleText {
@@ -48,62 +180,100 @@
align-items: center;
background-color: transparent;
border: 0;
+ color: inherit;
+ cursor: pointer;
display: flex;
flex-shrink: 0;
- height: 32px;
+ height: 100%;
justify-content: center;
margin-inline-start: auto;
padding: 0;
position: relative;
- width: 32px;
+ width: 36px;
}
#closeIcon {
- background:
- url(chrome://resources/images/icon_clear.svg) center/contain no-repeat;
+ -webkit-mask:
+ url(chrome://resources/images/icon_clear.svg)center/contain no-repeat;
+ background-color: currentColor;
display: block;
- height: 24px;
+ height: 18px;
position: relative;
- width: 24px;
+ width: 18px;
}
#thumbnail {
- background: var(--tabstrip-card-background-color);
+ align-items: center;
+ background: var(--tabstrip-tab-background-color);
+ display: flex;
flex: 1;
+ justify-content: center;
}
#thumbnailImg {
- height: 100%;
- object-fit: contain;
+ height: calc(var(--tabstrip-tab-height) - var(--tabstrip-tab-title-height));
+ object-fit: cover;
+ pointer-events: none;
+ width: var(--tabstrip-tab-width);
+ }
+
+ #thumbnailImg:not([src]) {
+ display: none;
+ pointer-events: none;
width: 100%;
}
/* Pinned tab styles */
- :host([pinned]) {
- height: 50px;
- width: 50px;
+ :host([pinned_]) {
+ height: var(--tabstrip-pinned-tab-size);
+ width: var(--tabstrip-pinned-tab-size);
}
- :host([pinned]) #title {
+ :host([pinned_]) #title {
border-block-end: 0;
height: 100%;
}
- :host([pinned]) #titleText,
- :host([pinned]) #close,
- :host([pinned]) #thumbnail {
+ :host([pinned_]) #titleText,
+ :host([pinned_]) #close,
+ :host([pinned_]) #thumbnail {
display: none;
}
+
+ :host([dragging_]) #dragPlaceholder {
+ background: var(--tabstrip-tab-background-color);
+ border-radius: var(--tabstrip-tab-border-radius);
+ height: 100%;
+ opacity: 0.5;
+ width: 100%;
+ }
+
+ /* When being dragged, the contents of the drag image needs to be off-screen
+ * with nothing else on top or below obscuring it. */
+ :host([dragging_]) #dragImage {
+ box-shadow: none;
+ position: absolute;
+ top: -999px;
+ }
</style>
-<header id="title">
- <span id="favicon"></span>
- <h2 id="titleText"></h2>
- <button id="close">
- <span id="closeIcon"></span>
- </button>
-</header>
+<div id="dragPlaceholder"></div>
+
+<div id="dragImage">
+ <header id="title">
+ <div id="faviconContainer">
+ <div id="progressSpinner"></div>
+ <div id="favicon"></div>
+ <div id="crashedIcon"></div>
+ <div id="blocked"></div>
+ </div>
+ <h2 id="titleText"></h2>
+ <button id="close">
+ <span id="closeIcon"></span>
+ </button>
+ </header>
-<div id="thumbnail">
- <img id="thumbnailImg">
+ <div id="thumbnail">
+ <img id="thumbnailImg">
+ </div>
</div>
diff --git a/chromium/chrome/browser/resources/tab_strip/tab.js b/chromium/chrome/browser/resources/tab_strip/tab.js
index 0b16488f0ca..a6908f2018a 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab.js
@@ -2,10 +2,12 @@
// 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 {assert} from 'chrome://resources/js/assert.m.js';
+import {getFavicon} from 'chrome://resources/js/icon.m.js';
import {CustomElement} from './custom_element.js';
-import {TabsApiProxy} from './tabs_api_proxy.js';
+import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
+import {TabData, TabNetworkState, TabsApiProxy} from './tabs_api_proxy.js';
export const DEFAULT_ANIMATION_DURATION = 125;
@@ -22,6 +24,11 @@ export class TabElement extends CustomElement {
/** @type {!HTMLElement} */ (this.shadowRoot.querySelector('#close'));
/** @private {!HTMLElement} */
+ this.dragImage_ =
+ /** @type {!HTMLElement} */ (
+ this.shadowRoot.querySelector('#dragImage'));
+
+ /** @private {!HTMLElement} */
this.faviconEl_ =
/** @type {!HTMLElement} */ (this.shadowRoot.querySelector('#favicon'));
@@ -34,54 +41,79 @@ export class TabElement extends CustomElement {
this.thumbnail_ =
/** @type {!Image} */ (this.shadowRoot.querySelector('#thumbnailImg'));
- /** @private {!Tab} */
+ /** @private {!TabData} */
this.tab_;
/** @private {!TabsApiProxy} */
this.tabsApi_ = TabsApiProxy.getInstance();
+ /** @private {!TabStripEmbedderProxy} */
+ this.embedderApi_ = TabStripEmbedderProxy.getInstance();
+
/** @private {!HTMLElement} */
this.titleTextEl_ = /** @type {!HTMLElement} */ (
this.shadowRoot.querySelector('#titleText'));
this.addEventListener('click', this.onClick_.bind(this));
+ this.addEventListener('contextmenu', this.onContextMenu_.bind(this));
this.closeButtonEl_.addEventListener('click', this.onClose_.bind(this));
}
- /** @return {!Tab} */
+ /** @return {!TabData} */
get tab() {
return this.tab_;
}
- /** @param {!Tab} tab */
+ /** @param {!TabData} tab */
set tab(tab) {
+ assert(this.tab_ !== tab);
this.toggleAttribute('active', tab.active);
- this.toggleAttribute('pinned', tab.pinned);
+ this.toggleAttribute('hide-icon_', !tab.showIcon);
+ this.toggleAttribute(
+ 'waiting_',
+ !tab.shouldHideThrobber &&
+ tab.networkState === TabNetworkState.WAITING);
+ this.toggleAttribute(
+ 'loading_',
+ !tab.shouldHideThrobber &&
+ tab.networkState === TabNetworkState.LOADING);
+ this.toggleAttribute('pinned_', tab.pinned);
+ this.toggleAttribute('blocked_', tab.blocked);
+ this.setAttribute('draggable', tab.pinned);
+ this.toggleAttribute('crashed_', tab.crashed);
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);
+ if (tab.networkState === TabNetworkState.WAITING ||
+ (tab.networkState === TabNetworkState.LOADING &&
+ tab.isDefaultFavicon)) {
+ this.faviconEl_.style.backgroundImage = 'none';
+ } else if (tab.favIconUrl) {
+ this.faviconEl_.style.backgroundImage = `url(${tab.favIconUrl})`;
+ } else {
+ this.faviconEl_.style.backgroundImage = getFavicon('');
}
// 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.tabsApi_.trackThumbnailForTab(tab.id);
}
this.tab_ = Object.freeze(tab);
}
/**
+ * @return {!HTMLElement}
+ */
+ getDragImage() {
+ return this.dragImage_;
+ }
+
+ /**
* @param {string} imgData
*/
updateThumbnail(imgData) {
@@ -95,6 +127,19 @@ export class TabElement extends CustomElement {
}
this.tabsApi_.activateTab(this.tab_.id);
+ this.embedderApi_.closeContainer();
+ }
+
+ /** @private */
+ onContextMenu_(event) {
+ event.preventDefault();
+
+ if (!this.tab_) {
+ return;
+ }
+
+ this.embedderApi_.showTabContextMenu(
+ this.tab_.id, event.clientX, event.clientY);
}
/**
@@ -111,6 +156,13 @@ export class TabElement extends CustomElement {
}
/**
+ * @param {boolean} dragging
+ */
+ setDragging(dragging) {
+ this.toggleAttribute('dragging_', dragging);
+ }
+
+ /**
* @return {!Promise}
*/
slideIn() {
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.html b/chromium/chrome/browser/resources/tab_strip/tab_list.html
index 680c562aa68..1b6056cd4d3 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_list.html
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.html
@@ -1,36 +1,28 @@
<style>
:host {
+ background: var(--tabstrip-background-color);
+ box-sizing: border-box;
display: flex;
+ min-width: fit-content;
padding: 16px;
- width: fit-content;
+ width: 100%;
}
#pinnedTabsContainer {
+ /* 4 pinned tabs should fit in the same space vertically as 1 unpinned
+ * tab. 30px is subtracted from the height of an unpinned tab as there
+ * are three 10px gaps to separate each of the 4 pinned tabs. */
+ --tabstrip-pinned-tab-size: calc((var(--tabstrip-tab-height) - 30px) / 4);
+
display: grid;
- grid-auto-columns: 50px;
+ grid-auto-columns: var(--tabstrip-pinned-tab-size);
grid-auto-flow: column;
grid-gap: 10px;
- grid-template-rows: repeat(4, 50px);
+ grid-template-rows: repeat(4, var(--tabstrip-pinned-tab-size));
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 {
+ #pinnedTabsContainer:empty {
display: none;
}
@@ -43,9 +35,5 @@
}
</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="pinnedTabsContainer"></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
index dd72aec77bd..4d747e65f62 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_list.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.js
@@ -4,12 +4,29 @@
import './tab.js';
+import {assert} from 'chrome://resources/js/assert.m.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;
+import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
+import {TabData, TabsApiProxy} from './tabs_api_proxy.js';
+
+/**
+ * The amount of padding to leave between the edge of the screen and the active
+ * tab when auto-scrolling. This should leave some room to show the previous or
+ * next tab to afford to users that there more tabs if the user scrolls.
+ * @const {number}
+ */
+const SCROLL_PADDING = 32;
+
+/**
+ * @param {!Element} element
+ * @return {boolean}
+ */
+function isTabElement(element) {
+ return element.tagName === 'TABSTRIP-TAB';
+}
class TabListElement extends CustomElement {
static get template() {
@@ -28,27 +45,45 @@ class TabListElement extends CustomElement {
*/
this.animationPromises = Promise.resolve();
+ /**
+ * The TabElement that is currently being dragged.
+ * @private {!TabElement|undefined}
+ */
+ this.draggedItem_;
+
/** @private {!Element} */
this.pinnedTabsContainerElement_ =
/** @type {!Element} */ (
this.shadowRoot.querySelector('#pinnedTabsContainer'));
+ /** @private {!Element} */
+ this.scrollingParent_ = document.documentElement;
+
+ /** @private {!TabStripEmbedderProxy} */
+ this.tabStripEmbedderProxy_ = TabStripEmbedderProxy.getInstance();
+
/** @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('theme-changed', () => this.fetchAndUpdateColors_());
+ this.tabStripEmbedderProxy_.observeThemeChanges();
addWebUIListener(
'tab-thumbnail-updated', this.tabThumbnailUpdated_.bind(this));
+
+ this.addEventListener(
+ 'dragstart', (e) => this.onDragStart_(/** @type {!DragEvent} */ (e)));
+ this.addEventListener(
+ 'dragend', (e) => this.onDragEnd_(/** @type {!DragEvent} */ (e)));
+ this.addEventListener(
+ 'dragover', (e) => this.onDragOver_(/** @type {!DragEvent} */ (e)));
+ document.addEventListener(
+ 'visibilitychange', () => this.moveOrScrollToActiveTab_());
}
/**
@@ -60,33 +95,23 @@ class TabListElement extends CustomElement {
}
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));
+ this.fetchAndUpdateColors_();
+ this.tabsApi_.getTabs().then(tabs => {
+ tabs.forEach(tab => this.onTabCreated_(tab));
+ this.moveOrScrollToActiveTab_();
+
+ addWebUIListener('tab-created', tab => this.onTabCreated_(tab));
+ addWebUIListener(
+ 'tab-moved', (tabId, newIndex) => this.onTabMoved_(tabId, newIndex));
+ addWebUIListener('tab-removed', tabId => this.onTabRemoved_(tabId));
+ addWebUIListener('tab-updated', tab => this.onTabUpdated_(tab));
+ addWebUIListener(
+ 'tab-active-changed', tabId => this.onTabActivated_(tabId));
});
}
/**
- * @param {!Tab} tab
+ * @param {!TabData} tab
* @return {!TabElement}
* @private
*/
@@ -106,6 +131,24 @@ class TabListElement extends CustomElement {
this.shadowRoot.querySelector(`tabstrip-tab[data-tab-id="${tabId}"]`));
}
+ /** @private */
+ fetchAndUpdateColors_() {
+ this.tabStripEmbedderProxy_.getColors().then(colors => {
+ for (const [cssVariable, rgbaValue] of Object.entries(colors)) {
+ this.style.setProperty(cssVariable, rgbaValue);
+ }
+ });
+ }
+
+ /**
+ * @return {?TabElement}
+ * @private
+ */
+ getActiveTab_() {
+ return /** @type {?TabElement} */ (
+ this.shadowRoot.querySelector('tabstrip-tab[active]'));
+ }
+
/**
* @param {!TabElement} tabElement
* @param {number} index
@@ -121,111 +164,207 @@ class TabListElement extends CustomElement {
} 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);
+ const offsetIndex =
+ index - this.pinnedTabsContainerElement_.childElementCount;
this.tabsContainerElement_.insertBefore(
tabElement, this.tabsContainerElement_.childNodes[offsetIndex]);
}
+ }
+
+ /** @private */
+ moveOrScrollToActiveTab_() {
+ const activeTab = this.getActiveTab_();
+ if (!activeTab) {
+ return;
+ }
- this.updatePinnedTabsState_();
+ if (!this.tabStripEmbedderProxy_.isVisible() && !activeTab.tab.pinned &&
+ this.tabsContainerElement_.firstChild !== activeTab) {
+ this.tabsApi_.moveTab(
+ activeTab.tab.id, this.pinnedTabsContainerElement_.childElementCount);
+ } else {
+ this.scrollToTab_(activeTab);
+ }
}
/**
- * @param {!TabActivatedInfo} activeInfo
+ * @param {!DragEvent} event
* @private
*/
- onTabActivated_(activeInfo) {
- if (activeInfo.windowId !== this.windowId_) {
+ onDragEnd_(event) {
+ if (!this.draggedItem_) {
return;
}
- const previouslyActiveTab =
- this.shadowRoot.querySelector('tabstrip-tab[active]');
- if (previouslyActiveTab) {
- previouslyActiveTab.tab = /** @type {!Tab} */ (
- Object.assign({}, previouslyActiveTab.tab, {active: false}));
+ this.draggedItem_.setDragging(false);
+ this.draggedItem_ = undefined;
+ }
+
+ /**
+ * @param {!DragEvent} event
+ * @private
+ */
+ onDragOver_(event) {
+ event.preventDefault();
+ const dragOverItem = event.path.find((pathItem) => {
+ return pathItem !== this.draggedItem_ && isTabElement(pathItem);
+ });
+
+ if (!dragOverItem || !this.draggedItem_ || !dragOverItem.tab.pinned) {
+ return;
}
- const newlyActiveTab = this.findTabElement_(activeInfo.tabId);
- newlyActiveTab.tab = /** @type {!Tab} */ (
- Object.assign({}, newlyActiveTab.tab, {active: true}));
+ event.dataTransfer.dropEffect = 'move';
+
+ const dragOverIndex =
+ Array.from(dragOverItem.parentNode.children).indexOf(dragOverItem);
+ this.tabsApi_.moveTab(this.draggedItem_.tab.id, dragOverIndex);
}
/**
- * @param {!Tab} tab
+ * @param {!DragEvent} event
* @private
*/
- onTabCreated_(tab) {
- if (tab.windowId !== this.windowId_) {
+ onDragStart_(event) {
+ const draggedItem = event.path[0];
+ if (!isTabElement(draggedItem)) {
return;
}
- const tabElement = this.createTabElement_(tab);
- this.insertTabOrMoveTo_(tabElement, tab.index);
- this.addAnimationPromise_(tabElement.slideIn());
+ assert(draggedItem.tab.pinned);
+ this.draggedItem_ = /** @type {!TabElement} */ (draggedItem);
+ this.draggedItem_.setDragging(true);
+ event.dataTransfer.effectAllowed = 'move';
+ event.dataTransfer.setDragImage(
+ this.draggedItem_.getDragImage(),
+ event.pageX - this.draggedItem_.offsetLeft,
+ event.pageY - this.draggedItem_.offsetTop);
}
/**
* @param {number} tabId
- * @param {!TabMovedInfo} moveInfo
* @private
*/
- onTabMoved_(tabId, moveInfo) {
- if (moveInfo.windowId !== this.windowId_) {
- return;
+ onTabActivated_(tabId) {
+ // There may be more than 1 TabElement marked as active if other events
+ // have updated a Tab to have an active state. For example, if a
+ // tab is created with an already active state, there may be 2 active
+ // TabElements: the newly created tab and the previously active tab.
+ this.shadowRoot.querySelectorAll('tabstrip-tab[active]')
+ .forEach((previouslyActiveTab) => {
+ if (previouslyActiveTab.tab.id !== tabId) {
+ previouslyActiveTab.tab = /** @type {!TabData} */ (
+ Object.assign({}, previouslyActiveTab.tab, {active: false}));
+ }
+ });
+
+ const newlyActiveTab = this.findTabElement_(tabId);
+ if (newlyActiveTab) {
+ newlyActiveTab.tab = /** @type {!TabData} */ (
+ Object.assign({}, newlyActiveTab.tab, {active: true}));
+ this.moveOrScrollToActiveTab_();
}
+ }
- const movedTab = this.findTabElement_(tabId);
- if (movedTab) {
- this.insertTabOrMoveTo_(movedTab, moveInfo.toIndex);
+ /**
+ * @param {!TabData} tab
+ * @private
+ */
+ onTabCreated_(tab) {
+ const tabElement = this.createTabElement_(tab);
+
+ if (tab.active && !tab.pinned &&
+ tab.index !== this.pinnedTabsContainerElement_.childElementCount) {
+ // Newly created active tabs should first be moved to the very beginning
+ // of the tab strip to enforce the tab strip's most recently used ordering
+ this.tabsApi_
+ .moveTab(tab.id, this.pinnedTabsContainerElement_.childElementCount)
+ .then(() => {
+ this.insertTabOrMoveTo_(
+ tabElement, this.pinnedTabsContainerElement_.childElementCount);
+ this.addAnimationPromise_(tabElement.slideIn());
+ });
+ } else {
+ this.insertTabOrMoveTo_(tabElement, tab.index);
+ this.addAnimationPromise_(tabElement.slideIn());
}
}
/**
* @param {number} tabId
- * @param {!WindowRemoveInfo} removeInfo
+ * @param {number} newIndex
* @private
*/
- onTabRemoved_(tabId, removeInfo) {
- if (removeInfo.windowId !== this.windowId_) {
- return;
+ onTabMoved_(tabId, newIndex) {
+ const movedTab = this.findTabElement_(tabId);
+ if (movedTab) {
+ this.insertTabOrMoveTo_(movedTab, newIndex);
+ if (movedTab.tab.active) {
+ this.scrollToTab_(movedTab);
+ }
}
+ }
+ /**
+ * @param {number} tabId
+ * @private
+ */
+ onTabRemoved_(tabId) {
const tabElement = this.findTabElement_(tabId);
if (tabElement) {
- this.addAnimationPromise_(new Promise(async resolve => {
- await tabElement.slideOut();
- this.updatePinnedTabsState_();
- resolve();
- }));
+ this.addAnimationPromise_(tabElement.slideOut());
}
}
/**
- * @param {number} tabId
- * @param {!Tab} changeInfo
- * @param {!Tab} tab
+ * @param {!TabData} tab
* @private
*/
- onTabUpdated_(tabId, changeInfo, tab) {
- if (tab.windowId !== this.windowId_) {
+ onTabUpdated_(tab) {
+ const tabElement = this.findTabElement_(tab.id);
+ if (!tabElement) {
return;
}
- const tabElement = this.findTabElement_(tabId);
- if (tabElement) {
- tabElement.tab = tab;
+ const previousTab = tabElement.tab;
+ 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);
+ if (previousTab.pinned !== tab.pinned) {
+ // If the tab is being pinned or unpinned, we need to move it to its new
+ // location
+ this.insertTabOrMoveTo_(tabElement, tab.index);
+ if (tab.active) {
+ this.scrollToTab_(tabElement);
}
}
}
/**
+ * @param {!TabElement} tabElement
+ * @private
+ */
+ scrollToTab_(tabElement) {
+ this.animationPromises.then(() => {
+ const screenLeft = this.scrollingParent_.scrollLeft;
+ const screenRight = screenLeft + this.scrollingParent_.offsetWidth;
+
+ if (screenLeft > tabElement.offsetLeft) {
+ // If the element's left is to the left of the visible screen, scroll
+ // such that the element's left edge is aligned with the screen's edge
+ this.scrollingParent_.scrollLeft =
+ tabElement.offsetLeft - SCROLL_PADDING;
+ } else if (screenRight < tabElement.offsetLeft + tabElement.offsetWidth) {
+ // If the element's right is to the right of the visible screen, scroll
+ // such that the element's right edge is aligned with the screen's right
+ // edge.
+ this.scrollingParent_.scrollLeft = tabElement.offsetLeft +
+ tabElement.offsetWidth - this.scrollingParent_.offsetWidth +
+ SCROLL_PADDING;
+ }
+ });
+ }
+
+ /**
* @param {number} tabId
* @param {string} imgData
* @private
@@ -236,14 +375,6 @@ class TabListElement extends CustomElement {
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
index 088f0ea0097..20b58a70a3c 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_strip.html
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip.html
@@ -13,30 +13,15 @@
--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);
- }
+ --tabstrip-background-color: $i18n{frameColor};
+ --tabstrip-tab-height: 216px;
+ --tabstrip-tab-width: 288px;
+ --tabstrip-tab-border-radius: 8px;
+ --tabstrip-tab-active-border-color: rgb(var(--google-blue-500-rgb));
}
body {
background: var(--tabstrip-background-color);
- color: var(--tabstrip-primary-text-color);
margin: 0;
padding: 0;
}
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js b/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
new file mode 100644
index 00000000000..6852de8b29f
--- /dev/null
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
@@ -0,0 +1,39 @@
+// 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, addWebUIListener, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+
+export class TabStripEmbedderProxy {
+ /** @return {boolean} */
+ isVisible() {
+ return document.visibilityState === 'visible';
+ }
+
+ /**
+ * @return {!Promise<!Object<string, string>>} Object with CSS variables
+ * as keys and rgba strings as values
+ */
+ getColors() {
+ return sendWithPromise('getThemeColors');
+ }
+
+ observeThemeChanges() {
+ chrome.send('observeThemeChanges');
+ }
+
+ /**
+ * @param {number} tabId
+ * @param {number} locationX
+ * @param {number} locationY
+ */
+ showTabContextMenu(tabId, locationX, locationY) {
+ chrome.send('showTabContextMenu', [tabId, locationX, locationY]);
+ }
+
+ closeContainer() {
+ chrome.send('closeContainer');
+ }
+}
+
+addSingletonGetter(TabStripEmbedderProxy);
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
index 72257fd7930..97074dac942 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
@@ -39,6 +39,66 @@
use_base_dir="false"
type="chrome_html"
compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_ALERT_INDICATOR_JS"
+ file="${root_gen_dir}/chrome/browser/resources/tab_strip/alert_indicator.js"
+ use_base_dir="false"
+ type="chrome_html"
+ compress="gzip"/>
+ <structure
+ name="IDR_TAB_STRIP_EMBEDDER_PROXY_JS"
+ file="tab_strip_embedder_proxy.js"
+ type="chrome_html"
+ compress="gzip"/>
</structures>
+
+ <includes>
+ <!-- Alert indicators -->
+ <include
+ name="IDR_TAB_STRIP_PICTURE_IN_PICTURE_ALT_SVG"
+ file="alert_indicators/picture_in_picture_alt.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_SERIAL_PORT_SVG"
+ file="alert_indicators/serial_port.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_AUDIO_MUTING_ROUNDED_SVG"
+ file="alert_indicators/tab_audio_muting_rounded.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_AUDIO_ROUNDED_SVG"
+ file="alert_indicators/tab_audio_rounded.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_BLUETOOTH_CONNECTED_SVG"
+ file="alert_indicators/tab_bluetooth_connected.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_MEDIA_CAPTURING_WITH_ARROW_SVG"
+ file="alert_indicators/tab_media_capturing_with_arrow.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_MEDIA_RECORING_SVG"
+ file="alert_indicators/tab_media_recording.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_TAB_USB_CONNECTED_SVG"
+ file="alert_indicators/tab_usb_connected.svg"
+ type="BINDATA"
+ compress="gzip" />
+ <include
+ name="IDR_TAB_STRIP_VR_HEADSET_SVG"
+ file="alert_indicators/vr_headset.svg"
+ type="BINDATA"
+ compress="gzip" />
+ </includes>
</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
index 9ce6ad61f28..34b13b9f75f 100644
--- a/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
+++ b/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
@@ -2,23 +2,46 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+import {addSingletonGetter, sendWithPromise} 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,
- };
- }
+/**
+ * Must be kept in sync with TabNetworkState from
+ * //chrome/browser/ui/tabs/tab_network_state.h.
+ * @enum {number}
+ */
+export const TabNetworkState = {
+ NONE: 0,
+ WAITING: 1,
+ LOADING: 2,
+ ERROR: 3,
+};
+
+/**
+ * @typedef {{
+ * active: boolean,
+ * blocked: boolean,
+ * crashed: boolean,
+ * favIconUrl: (string|undefined),
+ * id: number,
+ * index: number,
+ * isDefaultFavicon: boolean,
+ * networkState: !TabNetworkState,
+ * pinned: boolean,
+ * shouldHideThrobber: boolean,
+ * showIcon: boolean,
+ * title: string,
+ * url: string,
+ * }}
+ */
+export let TabData;
+
+/** @typedef {!Tab} */
+let ExtensionsApiTab;
+export class TabsApiProxy {
/**
* @param {number} tabId
- * @return {!Promise<!Tab>}
+ * @return {!Promise<!ExtensionsApiTab>}
*/
activateTab(tabId) {
return new Promise(resolve => {
@@ -27,18 +50,10 @@ export class TabsApiProxy {
}
/**
- * @return {!Promise<!ChromeWindow>}
+ * @return {!Promise<!Array<!TabData>>}
*/
- 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);
- });
- });
+ getTabs() {
+ return sendWithPromise('getTabs');
}
/**
@@ -54,7 +69,7 @@ export class TabsApiProxy {
/**
* @param {number} tabId
* @param {number} newIndex
- * @return {!Promise<!Tab>}
+ * @return {!Promise<!ExtensionsApiTab>}
*/
moveTab(tabId, newIndex) {
return new Promise(resolve => {
@@ -63,6 +78,13 @@ export class TabsApiProxy {
});
});
}
+
+ /**
+ * @param {number} tabId
+ */
+ trackThumbnailForTab(tabId) {
+ chrome.send('addTrackedTab', [tabId]);
+ }
}
addSingletonGetter(TabsApiProxy);
diff --git a/chromium/chrome/browser/resources/tab_strip/types.js b/chromium/chrome/browser/resources/tab_strip/types.js
deleted file mode 100644
index 6496711a0da..00000000000
--- a/chromium/chrome/browser/resources/tab_strip/types.js
+++ /dev/null
@@ -1,32 +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 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 d4d21445df1..d7812aa300e 100644
--- a/chromium/chrome/browser/resources/usb_internals/BUILD.gn
+++ b/chromium/chrome/browser/resources/usb_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 = [
@@ -37,3 +38,23 @@ js_library("descriptor_panel") {
"//ui/webui/resources/js:cr",
]
}
+
+grit("resources") {
+ source = "resources.grd"
+
+ # The .grd contains references to generated files.
+ source_is_generated = true
+ outputs = [
+ "grit/usb_internals_resources.h",
+ "usb_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/usb_internals:mojo_bindings_js",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/usb_internals/resources.grd b/chromium/chrome/browser/resources/usb_internals/resources.grd
new file mode 100644
index 00000000000..48bc89841bd
--- /dev/null
+++ b/chromium/chrome/browser/resources/usb_internals/resources.grd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0"
+ current_release="1"
+ output_all_resource_defines="false">
+ <outputs>
+ <output filename="grit/usb_internals_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="usb_internals_resources.pak" type="data_package" />
+ </outputs>
+ <release seq="1">
+ <includes>
+ <include name="IDR_USB_INTERNALS_CSS"
+ file="usb_internals.css"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_USB_INTERNALS_DESCRIPTOR_PANEL_JS"
+ file="descriptor_panel.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_USB_INTERNALS_DEVICES_PAGE_JS"
+ file="devices_page.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_USB_INTERNALS_HTML"
+ file="usb_internals.html"
+ flattenhtml="true"
+ allowexternalscript="true"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_USB_INTERNALS_JS"
+ file="usb_internals.js"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_USB_INTERNALS_MOJOM_LITE_JS"
+ file="${root_gen_dir}\chrome\browser\ui\webui\usb_internals\usb_internals.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ </includes>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/user_manager/shared_styles.html b/chromium/chrome/browser/resources/user_manager/shared_styles.html
index 3bc6fc49a49..9d3367b9e81 100644
--- a/chromium/chrome/browser/resources/user_manager/shared_styles.html
+++ b/chromium/chrome/browser/resources/user_manager/shared_styles.html
@@ -39,8 +39,8 @@
@media (prefers-color-scheme: dark) {
.product-logo {
content: -webkit-image-set(
- url(../../../app/theme/default_100_percent/%DISTRIBUTION%/product_logo_white.png) 1x,
- url(../../../app/theme/default_200_percent/%DISTRIBUTION%/product_logo_white.png) 2x);
+ url(../../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo_white.png) 1x,
+ url(../../../../components/resources/default_200_percent/%DISTRIBUTION%/product_logo_white.png) 2x);
}
}
</style>
diff --git a/chromium/chrome/browser/resources/vr/OWNERS b/chromium/chrome/browser/resources/vr/OWNERS
index 33672fa4bbe..f8d52f36333 100644
--- a/chromium/chrome/browser/resources/vr/OWNERS
+++ b/chromium/chrome/browser/resources/vr/OWNERS
@@ -1,3 +1,5 @@
+alcooper@chromium.org
+bialpio@chromium.org
cjgrant@chromium.org
tiborg@chromium.org
diff --git a/chromium/chrome/browser/resources/webapks/BUILD.gn b/chromium/chrome/browser/resources/webapks/BUILD.gn
index 6e4c0a57cda..2a502903daa 100644
--- a/chromium/chrome/browser/resources/webapks/BUILD.gn
+++ b/chromium/chrome/browser/resources/webapks/BUILD.gn
@@ -12,9 +12,8 @@ js_type_check("closure_compile") {
js_library("about_webapks") {
deps = [
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:util.m",
]
externs_list = [ "$externs_path/chrome_send.js" ]
}
diff --git a/chromium/chrome/browser/resources/webapks/about_webapks.html b/chromium/chrome/browser/resources/webapks/about_webapks.html
index f09ce2c5d08..4e91c526f30 100644
--- a/chromium/chrome/browser/resources/webapks/about_webapks.html
+++ b/chromium/chrome/browser/resources/webapks/about_webapks.html
@@ -11,12 +11,8 @@ about:webapks template page
<title>About WebAPKs</title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="about_webapks.css">
- <link rel="import" href="chrome://resources/html/cr.html">
- <link rel="import" href="chrome://resources/html/load_time_data.html">
- <link rel="import" href="chrome://resources/html/util.html">
- <script src="chrome://webapks/webapks.js"></script>
- <script src="chrome://webapks/strings.js"></script>
+ <script type="module" src="webapks.js"></script>
</head>
<body>
diff --git a/chromium/chrome/browser/resources/webapks/about_webapks.js b/chromium/chrome/browser/resources/webapks/about_webapks.js
index b21be02901e..10bc849c424 100644
--- a/chromium/chrome/browser/resources/webapks/about_webapks.js
+++ b/chromium/chrome/browser/resources/webapks/about_webapks.js
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import './strings.m.js';
+
+import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
+import {$, createElementWithClassName} from 'chrome://resources/js/util.m.js';
+
/**
* @typedef {{
* name: string,
@@ -54,17 +59,6 @@ function createElementWithTextAndClass(text, type, className) {
}
/**
- * Callback from the backend with the information of a WebAPK to display.
- * This will be called once per WebAPK.
- *
- * @param {!WebApkInfo} webApkInfo Object with information about an
- * installed WebAPK.
- */
-function returnWebApkInfo(webApkInfo) {
- addWebApk(webApkInfo);
-}
-
-/**
* @param {HTMLElement} webApkList List of elements which contain WebAPK
* attributes.
* @param {string} label Text that identifies the new element.
@@ -96,7 +90,7 @@ function addWebApkButton(webApkList, text, callback) {
/**
* Adds a new entry to the page with the information of a WebAPK.
*
- * @param {WebApkInfo} webApkInfo Information about an installed WebAPK.
+ * @param {!WebApkInfo} webApkInfo Information about an installed WebAPK.
*/
function addWebApk(webApkInfo) {
/** @type {HTMLElement} */ const webApkList = $('webapk-list');
@@ -160,5 +154,8 @@ function addWebApk(webApkInfo) {
}
document.addEventListener('DOMContentLoaded', function() {
+ // Add a WebUI listener for the 'web-apk-info' event emmitted from the
+ // backend. This will be triggered once per WebAPK.
+ addWebUIListener('web-apk-info', addWebApk);
chrome.send('requestWebApksInfo');
});
diff --git a/chromium/chrome/browser/resources/welcome/BUILD.gn b/chromium/chrome/browser/resources/welcome/BUILD.gn
index ad2a0c5b1a2..f82bd8f077e 100644
--- a/chromium/chrome/browser/resources/welcome/BUILD.gn
+++ b/chromium/chrome/browser/resources/welcome/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
group("closure_compile") {
deps = [
@@ -14,6 +15,11 @@ group("closure_compile") {
}
js_type_check("welcome_files") {
+ is_polymer3 = true
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/welcome/",
+ "js_module_root=./gen/chrome/browser/resources/welcome/",
+ ]
deps = [
":landing_view",
":signin_view",
@@ -26,13 +32,14 @@ js_library("landing_view") {
":landing_view_proxy",
":navigation_behavior",
":welcome_browser_proxy",
- "//ui/webui/resources/js:load_time_data",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:load_time_data.m",
]
}
js_library("landing_view_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/metrics_private.js" ]
}
@@ -42,19 +49,21 @@ js_library("signin_view") {
":navigation_behavior",
":signin_view_proxy",
":welcome_browser_proxy",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
js_library("signin_view_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/metrics_private.js" ]
}
js_library("navigation_behavior") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:assert.m",
]
}
@@ -65,14 +74,45 @@ js_library("welcome_app") {
"./set_as_default/:nux_set_as_default_proxy",
"./shared:bookmark_proxy",
"./shared:nux_types",
- "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager",
- "//ui/webui/resources/js:load_time_data",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m",
+ "//ui/webui/resources/js:load_time_data.m",
]
}
js_library("welcome_browser_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/chrome_send.js" ]
}
+
+polymer_modulizer("welcome_app") {
+ js_file = "welcome_app.js"
+ html_file = "welcome_app.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("landing_view") {
+ js_file = "landing_view.js"
+ html_file = "landing_view.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("signin_view") {
+ js_file = "signin_view.js"
+ html_file = "signin_view.html"
+ html_type = "v3-ready"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":landing_view_module",
+ ":signin_view_module",
+ ":welcome_app_module",
+ "./google_apps:nux_google_apps_module",
+ "./ntp_background:nux_ntp_background_module",
+ "./set_as_default:nux_set_as_default_module",
+ "./shared:polymer3_elements",
+ ]
+}
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn b/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn
index 6566c5e490b..f6f678ed905 100644
--- a/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn
+++ b/chromium/chrome/browser/resources/welcome/google_apps/BUILD.gn
@@ -3,8 +3,14 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/welcome/",
+ "js_module_root=gen/chrome/browser/resources/welcome/",
+ ]
+ is_polymer3 = true
deps = [
":google_app_proxy",
":google_apps_metrics_proxy",
@@ -20,16 +26,17 @@ js_library("nux_google_apps") {
"../shared:bookmark_proxy",
"../shared:nux_types",
"../shared:step_indicator",
- "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:i18n_behavior",
- "//ui/webui/resources/js:util",
+ "//third_party/polymer/v3_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:i18n_behavior.m",
+ "//ui/webui/resources/js:util.m",
]
}
js_library("google_app_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [ "$externs_path/chrome_send.js" ]
}
@@ -39,3 +46,9 @@ js_library("google_apps_metrics_proxy") {
"../shared:module_metrics_proxy",
]
}
+
+polymer_modulizer("nux_google_apps") {
+ js_file = "nux_google_apps.js"
+ html_file = "nux_google_apps.html"
+ html_type = "v3-ready"
+}
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.html b/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.html
deleted file mode 100644
index 3c50ce8ea88..00000000000
--- a/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="google_app_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.js b/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.js
index b4edc677e8a..63d890d8cf6 100644
--- a/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/google_apps/google_app_proxy.js
@@ -2,69 +2,65 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {BookmarkListItem} from '../shared/nux_types.js';
+
+/**
+ * NuxGoogleAppsSelections enum.
+ * These values are persisted to logs and should not be renumbered or
+ * re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+const NuxGoogleAppsSelections = {
+ GMAIL_DEPRECATED: 0,
+ YOU_TUBE: 1,
+ MAPS: 2,
+ TRANSLATE: 3,
+ NEWS: 4,
+ CHROME_WEB_STORE: 5,
+};
+
+/** @interface */
+export class GoogleAppProxy {
/**
- * NuxGoogleAppsSelections enum.
- * These values are persisted to logs and should not be renumbered or
- * re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
+ * Google app IDs are local to the list of Google apps, so their icon must
+ * be cached by the handler that provided the IDs.
+ * @param {number} appId
*/
- const NuxGoogleAppsSelections = {
- GMAIL_DEPRECATED: 0,
- YOU_TUBE: 1,
- MAPS: 2,
- TRANSLATE: 3,
- NEWS: 4,
- CHROME_WEB_STORE: 5,
- };
+ cacheBookmarkIcon(appId) {}
- /** @interface */
- class GoogleAppProxy {
- /**
- * Google app IDs are local to the list of Google apps, so their icon must
- * be cached by the handler that provided the IDs.
- * @param {number} appId
- */
- cacheBookmarkIcon(appId) {}
+ /**
+ * Returns a promise for an array of Google apps.
+ * @return {!Promise<!Array<!BookmarkListItem>>}
+ */
+ getAppList() {}
- /**
- * Returns a promise for an array of Google apps.
- * @return {!Promise<!Array<!welcome.BookmarkListItem>>}
- */
- getAppList() {}
+ /**
+ * @param {number} providerId This should match one of the histogram enum
+ * value for NuxGoogleAppsSelections.
+ */
+ recordProviderSelected(providerId) {}
+}
- /**
- * @param {number} providerId This should match one of the histogram enum
- * value for NuxGoogleAppsSelections.
- */
- recordProviderSelected(providerId) {}
+/** @implements {GoogleAppProxy} */
+export class GoogleAppProxyImpl {
+ /** @override */
+ cacheBookmarkIcon(appId) {
+ chrome.send('cacheGoogleAppIcon', [appId]);
}
- /** @implements {welcome.GoogleAppProxy} */
- class GoogleAppProxyImpl {
- /** @override */
- cacheBookmarkIcon(appId) {
- chrome.send('cacheGoogleAppIcon', [appId]);
- }
-
- /** @override */
- getAppList() {
- return cr.sendWithPromise('getGoogleAppsList');
- }
-
- /** @override */
- recordProviderSelected(providerId) {
- chrome.metricsPrivate.recordEnumerationValue(
- 'FirstRun.NewUserExperience.GoogleAppsSelection', providerId,
- Object.keys(NuxGoogleAppsSelections).length);
- }
+ /** @override */
+ getAppList() {
+ return sendWithPromise('getGoogleAppsList');
}
- cr.addSingletonGetter(GoogleAppProxyImpl);
+ /** @override */
+ recordProviderSelected(providerId) {
+ chrome.metricsPrivate.recordEnumerationValue(
+ 'FirstRun.NewUserExperience.GoogleAppsSelection', providerId,
+ Object.keys(NuxGoogleAppsSelections).length);
+ }
+}
- return {
- GoogleAppProxy: GoogleAppProxy,
- GoogleAppProxyImpl: GoogleAppProxyImpl,
- };
-});
+addSingletonGetter(GoogleAppProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.html b/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.html
deleted file mode 100644
index 222483c7329..00000000000
--- a/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="../shared/module_metrics_proxy.html">
-<script src="google_apps_metrics_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.js b/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.js
index 77886462fcd..529d4d63222 100644
--- a/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/google_apps/google_apps_metrics_proxy.js
@@ -2,18 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
- class GoogleAppsMetricsProxyImpl extends welcome.ModuleMetricsProxyImpl {
- constructor() {
- super(
- 'FirstRun.NewUserExperience.GoogleAppsInteraction',
- welcome.NuxGoogleAppsInteractions);
- }
- }
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+import {ModuleMetricsProxyImpl, NuxGoogleAppsInteractions} from '../shared/module_metrics_proxy.js';
- cr.addSingletonGetter(GoogleAppsMetricsProxyImpl);
+export class GoogleAppsMetricsProxyImpl extends ModuleMetricsProxyImpl {
+ constructor() {
+ super(
+ 'FirstRun.NewUserExperience.GoogleAppsInteraction',
+ NuxGoogleAppsInteractions);
+ }
+}
- return {
- GoogleAppsMetricsProxyImpl: GoogleAppsMetricsProxyImpl,
- };
-});
+addSingletonGetter(GoogleAppsMetricsProxyImpl);
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 fd03465f37a..c5f78a599b2 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
@@ -1,214 +1,190 @@
-<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/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/util.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-icon/iron-icon.html">
-<link rel="import" href="../navigation_behavior.html">
-<link rel="import" href="../shared/animations_css.html">
-<link rel="import" href="../shared/bookmark_proxy.html">
-<link rel="import" href="../shared/chooser_shared_css.html">
-<link rel="import" href="../shared/i18n_setup.html">
-<link rel="import" href="../shared/step_indicator.html">
-<link rel="import" href="google_app_proxy.html">
-<link rel="import" href="google_apps_metrics_proxy.html">
-
-<dom-module id="nux-google-apps">
- <template>
- <style include="animations chooser-shared-css">
- .apps-ask {
- text-align: center;
- }
-
- .chrome-logo {
- content: url(../images/module_icons/google_light.svg);
- height: 38px;
- margin: auto;
- margin-bottom: 16px;
- width: 42px;
- }
-
- @media (prefers-color-scheme: dark) {
- .chrome-logo {
- content: url(../images/module_icons/google_dark.svg);
- }
- }
-
- h1 {
- color: var(--cr-primary-text-color);
- font-size: 1.5rem;
- font-weight: 500;
- margin: 0;
- margin-bottom: 48px;
- outline: none;
- }
-
- #appChooser {
- display: block;
- white-space: nowrap;
- }
-
- .button-bar {
- margin-top: 4rem;
- }
-
- .option {
- -webkit-appearance: none;
- align-items: center;
- border-radius: 8px;
- box-sizing: border-box;
- display: inline-flex;
- font-family: inherit;
- height: 7.5rem;
- justify-content: center;
- outline: 0;
- position: relative;
- transition-duration: 500ms;
- transition-property: box-shadow;
- vertical-align: bottom;
- width: 6.25rem;
- }
-
- .option:not(:first-of-type) {
- margin-inline-start: 1.5rem;
- }
-
- .option[active] {
- border: 1px solid var(--cr-checked-color);
- color: var(--cr-checked-color);
- font-weight: 500;
- }
-
- .option.keyboard-focused:focus {
- outline: var(--navi-keyboard-focus-color) solid 3px;
- }
-
- .option-name {
- flex-grow: 0;
- line-height: 1.25rem;
- text-align: center;
- white-space: normal;
- }
-
- .option-icon {
- background-position: center;
- background-repeat: no-repeat;
- background-size: contain;
- height: 2rem;
- margin: auto;
- width: 2rem;
- }
-
- .option-icon-shadow {
- background-color: var(--navi-option-icon-shadow-color);
- border-radius: 50%;
- display: flex;
- height: 3rem;
- margin-bottom: .25rem;
- width: 3rem;
- }
-
- .option iron-icon {
- --iron-icon-fill-color: var(--cr-card-background-color);
- background: var(--navi-check-icon-color);
- border-radius: 50%;
- display: none;
- height: .75rem;
- margin: 0;
- position: absolute;
- right: .375rem;
- top: .375rem;
- width: .75rem;
- }
-
- :host-context([dir=rtl]) .option iron-icon {
- left: .375rem;
- right: unset;
- }
-
- .option.keyboard-focused:focus iron-icon[icon='cr:check'],
- .option:hover iron-icon[icon='cr:check'],
- .option[active] iron-icon[icon='cr:check'] {
- display: block;
- }
-
- .option[active] iron-icon[icon='cr:check'] {
- background: var(--cr-checked-color);
- }
-
- /* App Icons */
- .gmail {
- content: -webkit-image-set(
- 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_WELCOME_YOUTUBE@1x) 1x,
- url(chrome://theme/IDS_WELCOME_YOUTUBE@2x) 2x);
- }
-
- .maps {
- content: -webkit-image-set(
- 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_WELCOME_TRANSLATE@1x) 1x,
- url(chrome://theme/IDS_WELCOME_TRANSLATE@2x) 2x);
- }
-
- .news {
- content: -webkit-image-set(
- 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_WELCOME_SEARCH@1x) 1x,
- url(chrome://theme/IDS_WELCOME_SEARCH@2x) 2x);
- }
- </style>
- <div class="apps-ask">
- <div class="chrome-logo" alt=""></div>
- <h1 tabindex="-1">$i18n{googleAppsDescription}</h1>
- <div id="appChooser">
- <div class="slide-in">
- <template is="dom-repeat" items="[[appList_]]">
- <button active$="[[item.selected]]"
- aria-pressed$="[[getAriaPressed_(item.selected)]]"
- on-click="onAppClick_" on-pointerdown="onAppPointerDown_"
- on-keyup="onAppKeyUp_" class="option">
- <div class="option-icon-shadow">
- <div class$="[[item.icon]] option-icon"></div>
- </div>
- <div class="option-name">[[item.name]]</div>
- <iron-icon icon="cr:check"></iron-icon>
- </button>
- </template>
- </div>
-
- <div class="button-bar">
- <cr-button id="noThanksButton" on-click="onNoThanksClicked_">
- $i18n{skip}
- </cr-button>
- <step-indicator model="[[indicatorModel]]"></step-indicator>
- <cr-button class="action-button" disabled$="[[!hasAppsSelected_]]"
- on-click="onGetStartedClicked_">
- $i18n{next}
- <iron-icon icon="cr:chevron-right"></iron-icon>
- </cr-button>
- </div>
- </div>
+<style include="animations chooser-shared-css">
+ .apps-ask {
+ text-align: center;
+ }
+
+ .chrome-logo {
+ content: url(../images/module_icons/google_light.svg);
+ height: 38px;
+ margin: auto;
+ margin-bottom: 16px;
+ width: 42px;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .chrome-logo {
+ content: url(../images/module_icons/google_dark.svg);
+ }
+ }
+
+ h1 {
+ color: var(--cr-primary-text-color);
+ font-size: 1.5rem;
+ font-weight: 500;
+ margin: 0;
+ margin-bottom: 48px;
+ outline: none;
+ }
+
+ #appChooser {
+ display: block;
+ white-space: nowrap;
+ }
+
+ .button-bar {
+ margin-top: 4rem;
+ }
+
+ .option {
+ -webkit-appearance: none;
+ align-items: center;
+ border-radius: 8px;
+ box-sizing: border-box;
+ display: inline-flex;
+ font-family: inherit;
+ height: 7.5rem;
+ justify-content: center;
+ outline: 0;
+ position: relative;
+ transition-duration: 500ms;
+ transition-property: box-shadow;
+ vertical-align: bottom;
+ width: 6.25rem;
+ }
+
+ .option:not(:first-of-type) {
+ margin-inline-start: 1.5rem;
+ }
+
+ .option[active] {
+ border: 1px solid var(--cr-checked-color);
+ color: var(--cr-checked-color);
+ font-weight: 500;
+ }
+
+ .option.keyboard-focused:focus {
+ outline: var(--navi-keyboard-focus-color) solid 3px;
+ }
+
+ .option-name {
+ flex-grow: 0;
+ line-height: 1.25rem;
+ text-align: center;
+ white-space: normal;
+ }
+
+ .option-icon {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ height: 2rem;
+ margin: auto;
+ width: 2rem;
+ }
+
+ .option-icon-shadow {
+ background-color: var(--navi-option-icon-shadow-color);
+ border-radius: 50%;
+ display: flex;
+ height: 3rem;
+ margin-bottom: .25rem;
+ width: 3rem;
+ }
+
+ .option iron-icon {
+ --iron-icon-fill-color: var(--cr-card-background-color);
+ background: var(--navi-check-icon-color);
+ border-radius: 50%;
+ display: none;
+ height: .75rem;
+ margin: 0;
+ position: absolute;
+ right: .375rem;
+ top: .375rem;
+ width: .75rem;
+ }
+
+ :host-context([dir=rtl]) .option iron-icon {
+ left: .375rem;
+ right: unset;
+ }
+
+ .option.keyboard-focused:focus iron-icon[icon='cr:check'],
+ .option:hover iron-icon[icon='cr:check'],
+ .option[active] iron-icon[icon='cr:check'] {
+ display: block;
+ }
+
+ .option[active] iron-icon[icon='cr:check'] {
+ background: var(--cr-checked-color);
+ }
+
+ /* App Icons */
+ .gmail {
+ content: -webkit-image-set(
+ 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_WELCOME_YOUTUBE@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_YOUTUBE@2x) 2x);
+ }
+
+ .maps {
+ content: -webkit-image-set(
+ 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_WELCOME_TRANSLATE@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_TRANSLATE@2x) 2x);
+ }
+
+ .news {
+ content: -webkit-image-set(
+ 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_WELCOME_SEARCH@1x) 1x,
+ url(chrome://theme/IDS_WELCOME_SEARCH@2x) 2x);
+ }
+</style>
+<div class="apps-ask">
+ <div class="chrome-logo" alt=""></div>
+ <h1 tabindex="-1">$i18n{googleAppsDescription}</h1>
+ <div id="appChooser">
+ <div class="slide-in">
+ <template is="dom-repeat" items="[[appList_]]">
+ <button active$="[[item.selected]]"
+ aria-pressed$="[[getAriaPressed_(item.selected)]]"
+ on-click="onAppClick_" on-pointerdown="onAppPointerDown_"
+ on-keyup="onAppKeyUp_" class="option">
+ <div class="option-icon-shadow">
+ <div class$="[[item.icon]] option-icon"></div>
+ </div>
+ <div class="option-name">[[item.name]]</div>
+ <iron-icon icon="cr:check"></iron-icon>
+ </button>
+ </template>
</div>
- </template>
- <script src="nux_google_apps.js"></script>
-</dom-module>
+
+ <div class="button-bar">
+ <cr-button id="noThanksButton" on-click="onNoThanksClicked_">
+ $i18n{skip}
+ </cr-button>
+ <step-indicator model="[[indicatorModel]]"></step-indicator>
+ <cr-button class="action-button" disabled$="[[!hasAppsSelected_]]"
+ on-click="onGetStartedClicked_">
+ $i18n{next}
+ <iron-icon icon="cr:chevron-right"></iron-icon>
+ </cr-button>
+ </div>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js
index 8452574c807..fd25a48c78f 100644
--- a/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js
+++ b/chromium/chrome/browser/resources/welcome/google_apps/nux_google_apps.js
@@ -2,7 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('welcome');
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/js/cr.m.js';
+import 'chrome://resources/js/util.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../shared/animations_css.js';
+import '../shared/chooser_shared_css.js';
+import '../shared/step_indicator.js';
+import '../strings.m.js';
+
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {isRTL} from 'chrome://resources/js/util.m.js';
+import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
+import {afterNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from '../navigation_behavior.js';
+import {BookmarkBarManager, BookmarkProxy, BookmarkProxyImpl} from '../shared/bookmark_proxy.js';
+import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
+import {BookmarkListItem, stepIndicatorModel} from '../shared/nux_types.js';
+
+import {GoogleAppProxy, GoogleAppProxyImpl} from './google_app_proxy.js';
+import {GoogleAppsMetricsProxyImpl} from './google_apps_metrics_proxy.js';
/**
* @typedef {{
@@ -14,29 +36,31 @@ cr.exportPath('welcome');
* selected: boolean,
* }}
*/
-welcome.AppItem;
+let AppItem;
/**
* @typedef {{
- * item: !welcome.AppItem,
+ * item: !AppItem,
* set: function(string, boolean):void
* }}
*/
-welcome.AppItemModel;
+let AppItemModel;
const KEYBOARD_FOCUSED = 'keyboard-focused';
Polymer({
is: 'nux-google-apps',
- behaviors: [welcome.NavigationBehavior, I18nBehavior],
+ _template: html`{__html_template__}`,
+
+ behaviors: [NavigationBehavior, I18nBehavior],
properties: {
- /** @type {welcome.stepIndicatorModel} */
+ /** @type {stepIndicatorModel} */
indicatorModel: Object,
/**
- * @type {!Array<!welcome.AppItem>}
+ * @type {!Array<!AppItem>}
* @private
*/
appList_: Array,
@@ -48,19 +72,19 @@ Polymer({
},
},
- /** @private {welcome.GoogleAppProxy} */
+ /** @private {GoogleAppProxy} */
appProxy_: null,
- /** @private {?welcome.ModuleMetricsManager} */
+ /** @private {?ModuleMetricsManager} */
metricsManager_: null,
- /** @private */
+ /** @private {boolean} */
finalized_: false,
- /** @private {welcome.BookmarkProxy} */
+ /** @private {BookmarkProxy} */
bookmarkProxy_: null,
- /** @private {welcome.BookmarkBarManager} */
+ /** @private {BookmarkBarManager} */
bookmarkBarManager_: null,
/** @private {boolean} */
@@ -68,18 +92,16 @@ Polymer({
/** @override */
ready: function() {
- this.appProxy_ = welcome.GoogleAppProxyImpl.getInstance();
- this.metricsManager_ = new welcome.ModuleMetricsManager(
- welcome.GoogleAppsMetricsProxyImpl.getInstance());
- this.bookmarkProxy_ = welcome.BookmarkProxyImpl.getInstance();
- this.bookmarkBarManager_ = welcome.BookmarkBarManager.getInstance();
+ this.appProxy_ = GoogleAppProxyImpl.getInstance();
+ this.metricsManager_ = new ModuleMetricsManager(
+ GoogleAppsMetricsProxyImpl.getInstance());
+ this.bookmarkProxy_ = BookmarkProxyImpl.getInstance();
+ this.bookmarkBarManager_ = BookmarkBarManager.getInstance();
},
/** @override */
attached: function() {
- Polymer.RenderStatus.afterNextRender(this, () => {
- Polymer.IronA11yAnnouncer.requestAvailability();
- });
+ afterNextRender(this, () => IronA11yAnnouncer.requestAvailability());
},
onRouteEnter: function() {
@@ -164,7 +186,7 @@ Polymer({
/**
* Handle toggling the apps selected.
- * @param {!{model: !welcome.AppItemModel}} e
+ * @param {!{model: !AppItemModel}} e
* @private
*/
onAppClick_: function(e) {
@@ -214,14 +236,14 @@ Polymer({
}
});
this.metricsManager_.recordGetStarted();
- welcome.navigateToNextStep();
+ navigateToNextStep();
},
/** @private */
onNoThanksClicked_: function() {
this.cleanUp_();
this.metricsManager_.recordNoThanks();
- welcome.navigateToNextStep();
+ navigateToNextStep();
},
/**
@@ -235,7 +257,7 @@ Polymer({
this.appList_.forEach(app => this.updateBookmark_(app));
} else {
this.appProxy_.getAppList().then(list => {
- this.appList_ = /** @type(!Array<!welcome.AppItem>) */ (list);
+ this.appList_ = /** @type(!Array<!AppItem>) */ (list);
this.appList_.forEach((app, index) => {
// Default select first few items.
app.selected = index < 3;
@@ -248,7 +270,7 @@ Polymer({
},
/**
- * @param {!welcome.AppItem} item
+ * @param {!AppItem} item
* @private
*/
updateBookmark_: function(item) {
diff --git a/chromium/chrome/browser/resources/welcome/landing_view.html b/chromium/chrome/browser/resources/welcome/landing_view.html
index 2ae537dc474..3446ebd2092 100644
--- a/chromium/chrome/browser/resources/welcome/landing_view.html
+++ b/chromium/chrome/browser/resources/welcome/landing_view.html
@@ -1,43 +1,26 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="animations action-link-style splash-pages-shared-css">
+ onboarding-background {
+ --animation-delay: 275ms;
+ }
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="landing_view_proxy.html">
-<link rel="import" href="navigation_behavior.html">
-<link rel="import" href="shared/action_link_style_css.html">
-<link rel="import" href="shared/i18n_setup.html">
-<link rel="import" href="shared/onboarding_background.html">
-<link rel="import" href="shared/splash_pages_shared_css.html">
-<link rel="import" href="welcome_browser_proxy.html">
+ h1 {
+ outline: none;
+ }
-<dom-module id="landing-view">
- <template>
- <style include="animations action-link-style splash-pages-shared-css">
- onboarding-background {
- --animation-delay: 275ms;
- }
-
- h1 {
- outline: none;
- }
-
- .action-button,
- .action-link {
- --animation-delay: 150ms;
- }
- </style>
- <div id="container">
- <onboarding-background class="fade-in"></onboarding-background>
- <h2 class="fade-in">$i18n{landingDescription}</h2>
- <h1 class="fade-in" tabindex="-1">$i18n{landingTitle}</h1>
- <cr-button class="action-button fade-in" on-click="onNewUserClick_">
- $i18n{landingNewUser}
- </cr-button>
- <button class="action-link fade-in" on-click="onExistingUserClick_">
- <span hidden$="[[!signinAllowed_]]">$i18n{landingExistingUser}</span>
- <span hidden$="[[signinAllowed_]]">$i18n{skip}</span>
- </button>
- </div>
- </template>
- <script src="landing_view.js"></script>
-</dom-module>
+ .action-button,
+ .action-link {
+ --animation-delay: 150ms;
+ }
+</style>
+<div id="container">
+ <onboarding-background class="fade-in"></onboarding-background>
+ <h2 class="fade-in">$i18n{landingDescription}</h2>
+ <h1 class="fade-in" tabindex="-1">$i18n{landingTitle}</h1>
+ <cr-button class="action-button fade-in" on-click="onNewUserClick_">
+ $i18n{landingNewUser}
+ </cr-button>
+ <button class="action-link fade-in" on-click="onExistingUserClick_">
+ <span hidden$="[[!signinAllowed_]]">$i18n{landingExistingUser}</span>
+ <span hidden$="[[signinAllowed_]]">$i18n{skip}</span>
+ </button>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/landing_view.js b/chromium/chrome/browser/resources/welcome/landing_view.js
index 94f6d4ad5e7..785bb5ea99a 100644
--- a/chromium/chrome/browser/resources/welcome/landing_view.js
+++ b/chromium/chrome/browser/resources/welcome/landing_view.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.
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
+import './shared/action_link_style_css.js';
+import './shared/onboarding_background.js';
+import './shared/splash_pages_shared_css.js';
+import '../strings.m.js';
+
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LandingViewProxy, LandingViewProxyImpl} from './landing_view_proxy.js';
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from './navigation_behavior.js';
+import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
+
Polymer({
is: 'landing-view',
- behaviors: [welcome.NavigationBehavior],
+ _template: html`{__html_template__}`,
+
+ behaviors: [NavigationBehavior],
properties: {
/** @private */
@@ -15,7 +31,7 @@ Polymer({
}
},
- /** @private {?welcome.LandingViewProxy} */
+ /** @private {?LandingViewProxy} */
landingViewProxy_: null,
/** @private {boolean} */
@@ -23,7 +39,7 @@ Polymer({
/** @override */
ready() {
- this.landingViewProxy_ = welcome.LandingViewProxyImpl.getInstance();
+ this.landingViewProxy_ = LandingViewProxyImpl.getInstance();
},
onRouteEnter: function() {
@@ -45,10 +61,10 @@ Polymer({
this.finalized_ = true;
this.landingViewProxy_.recordExistingUser();
if (this.signinAllowed_) {
- welcome.WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn(
+ WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn(
'chrome://welcome/returning-user');
} else {
- welcome.navigateTo(welcome.Routes.RETURNING_USER, 1);
+ navigateTo(Routes.RETURNING_USER, 1);
}
},
@@ -56,6 +72,6 @@ Polymer({
onNewUserClick_: function() {
this.finalized_ = true;
this.landingViewProxy_.recordNewUser();
- welcome.navigateTo(welcome.Routes.NEW_USER, 1);
+ navigateTo(Routes.NEW_USER, 1);
}
});
diff --git a/chromium/chrome/browser/resources/welcome/landing_view_proxy.html b/chromium/chrome/browser/resources/welcome/landing_view_proxy.html
deleted file mode 100644
index 84eb5be238e..00000000000
--- a/chromium/chrome/browser/resources/welcome/landing_view_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="landing_view_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/landing_view_proxy.js b/chromium/chrome/browser/resources/welcome/landing_view_proxy.js
index 1ccfbec4ef1..99e9819839e 100644
--- a/chromium/chrome/browser/resources/welcome/landing_view_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/landing_view_proxy.js
@@ -2,74 +2,69 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
- const NUX_LANDING_PAGE_INTERACTION_METRIC_NAME =
- 'FirstRun.NewUserExperience.LandingPageInteraction';
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
- /**
- * NuxLandingPageInteractions enum.
- * These values are persisted to logs and should not be renumbered or re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
- */
- const NuxLandingPageInteractions = {
- PageShown: 0,
- NavigatedAway: 1,
- NewUser: 2,
- ExistingUser: 3,
- };
+const NUX_LANDING_PAGE_INTERACTION_METRIC_NAME =
+ 'FirstRun.NewUserExperience.LandingPageInteraction';
- const NUX_LANDING_PAGE_INTERACTIONS_COUNT =
- Object.keys(NuxLandingPageInteractions).length;
+/**
+ * NuxLandingPageInteractions enum.
+ * These values are persisted to logs and should not be renumbered or re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+const NuxLandingPageInteractions = {
+ PageShown: 0,
+ NavigatedAway: 1,
+ NewUser: 2,
+ ExistingUser: 3,
+};
- /** @interface */
- class LandingViewProxy {
- recordPageShown() {}
+const NUX_LANDING_PAGE_INTERACTIONS_COUNT =
+ Object.keys(NuxLandingPageInteractions).length;
- recordNavigatedAway() {}
+/** @interface */
+export class LandingViewProxy {
+ recordPageShown() {}
- recordNewUser() {}
+ recordNavigatedAway() {}
- recordExistingUser() {}
- }
+ recordNewUser() {}
- /** @implements {welcome.LandingViewProxy} */
- class LandingViewProxyImpl {
- /** @override */
- recordPageShown() {
- this.recordInteraction_(NuxLandingPageInteractions.PageShown);
- }
+ recordExistingUser() {}
+}
- /** @override */
- recordNavigatedAway() {
- this.recordInteraction_(NuxLandingPageInteractions.NavigatedAway);
- }
+/** @implements {LandingViewProxy} */
+export class LandingViewProxyImpl {
+ /** @override */
+ recordPageShown() {
+ this.recordInteraction_(NuxLandingPageInteractions.PageShown);
+ }
- /** @override */
- recordNewUser() {
- this.recordInteraction_(NuxLandingPageInteractions.NewUser);
- }
+ /** @override */
+ recordNavigatedAway() {
+ this.recordInteraction_(NuxLandingPageInteractions.NavigatedAway);
+ }
- /** @override */
- recordExistingUser() {
- this.recordInteraction_(NuxLandingPageInteractions.ExistingUser);
- }
+ /** @override */
+ recordNewUser() {
+ this.recordInteraction_(NuxLandingPageInteractions.NewUser);
+ }
- /**
- * @param {number} interaction
- * @private
- */
- recordInteraction_(interaction) {
- chrome.metricsPrivate.recordEnumerationValue(
- NUX_LANDING_PAGE_INTERACTION_METRIC_NAME, interaction,
- NUX_LANDING_PAGE_INTERACTIONS_COUNT);
- }
+ /** @override */
+ recordExistingUser() {
+ this.recordInteraction_(NuxLandingPageInteractions.ExistingUser);
}
- cr.addSingletonGetter(LandingViewProxyImpl);
+ /**
+ * @param {number} interaction
+ * @private
+ */
+ recordInteraction_(interaction) {
+ chrome.metricsPrivate.recordEnumerationValue(
+ NUX_LANDING_PAGE_INTERACTION_METRIC_NAME, interaction,
+ NUX_LANDING_PAGE_INTERACTIONS_COUNT);
+ }
+}
- return {
- LandingViewProxy: LandingViewProxy,
- LandingViewProxyImpl: LandingViewProxyImpl,
- };
-});
+addSingletonGetter(LandingViewProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/navigation_behavior.html b/chromium/chrome/browser/resources/welcome/navigation_behavior.html
deleted file mode 100644
index 1488b4d3f79..00000000000
--- a/chromium/chrome/browser/resources/welcome/navigation_behavior.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/cr.html">
-
-<script src="navigation_behavior.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/welcome/navigation_behavior.js b/chromium/chrome/browser/resources/welcome/navigation_behavior.js
index 5e10ba646d0..c2c9445216d 100644
--- a/chromium/chrome/browser/resources/welcome/navigation_behavior.js
+++ b/chromium/chrome/browser/resources/welcome/navigation_behavior.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {afterNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
/**
* @fileoverview The NavigationBehavior is in charge of manipulating and
* watching window.history.state changes. The page is using the history
@@ -12,183 +15,172 @@
* or popping history state without actually changing the path.
*/
-cr.define('welcome', function() {
- 'use strict';
+/**
+ * Valid route pathnames.
+ * @enum {string}
+ */
+export const Routes = {
+ LANDING: 'landing',
+ NEW_USER: 'new-user',
+ RETURNING_USER: 'returning-user',
+};
- /**
- * Valid route pathnames.
- * @enum {string}
- */
- const Routes = {
- LANDING: 'landing',
- NEW_USER: 'new-user',
- RETURNING_USER: 'returning-user',
- };
+/**
+ * Regular expression that captures the leading slash, the content and the
+ * trailing slash in three different groups.
+ * @const {!RegExp}
+ */
+const CANONICAL_PATH_REGEX = /(^\/)([\/-\w]+)(\/$)/;
+const path = location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
+
+// Sets up history state based on the url path, unless it's already set (e.g.
+// when user uses browser-back button to get back on chrome://welcome/...).
+if (!history.state || !history.state.route || !history.state.step) {
+ switch (path) {
+ case `/${Routes.NEW_USER}`:
+ history.replaceState({route: Routes.NEW_USER, step: 1}, '', path);
+ break;
+ case `/${Routes.RETURNING_USER}`:
+ history.replaceState({route: Routes.RETURNING_USER, step: 1}, '', path);
+ break;
+ default:
+ history.replaceState(
+ {route: Routes.LANDING, step: Routes.LANDING}, '', '/');
+ }
+}
- /**
- * Regular expression that captures the leading slash, the content and the
- * trailing slash in three different groups.
- * @const {!RegExp}
- */
- const CANONICAL_PATH_REGEX = /(^\/)([\/-\w]+)(\/$)/;
- const path = location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
-
- // Sets up history state based on the url path, unless it's already set (e.g.
- // when user uses browser-back button to get back on chrome://welcome/...).
- if (!history.state || !history.state.route || !history.state.step) {
- switch (path) {
- case `/${Routes.NEW_USER}`:
- history.replaceState({route: Routes.NEW_USER, step: 1}, '', path);
- break;
- case `/${Routes.RETURNING_USER}`:
- history.replaceState({route: Routes.RETURNING_USER, step: 1}, '', path);
- break;
- default:
- history.replaceState(
- {route: Routes.LANDING, step: Routes.LANDING}, '', '/');
+/** @type {!Set<!PolymerElement>} */
+const routeObservers = new Set();
+
+/** @type {?PolymerElement} */
+let currentRouteElement;
+
+// Notifies all the elements that extended NavigationBehavior.
+function notifyObservers() {
+ if (currentRouteElement) {
+ (/** @type {{onRouteExit: Function}} */ (currentRouteElement))
+ .onRouteExit();
+ currentRouteElement = null;
+ }
+
+ const route = /** @type {!Routes} */ (history.state.route);
+ const step = history.state.step;
+ routeObservers.forEach(observer => {
+ (/** @type {{onRouteChange: Function}} */ (observer))
+ .onRouteChange(route, step);
+
+ // Modules are only attached to DOM if they're for the current route, so
+ // as long as the id of an element matches up to the current step, it
+ // means that element is for the current route.
+ if (observer.id == `step-${step}`) {
+ currentRouteElement = observer;
}
+ });
+
+ // If currentRouteElement is not null, it means there was a new route.
+ if (currentRouteElement) {
+ (/** @type {{onRouteEnter: Function}} */ (currentRouteElement))
+ .onRouteEnter();
+ (/** @type {{updateFocusForA11y: Function}} */ (currentRouteElement))
+ .updateFocusForA11y();
+ }
+}
+
+// Notifies all elements when browser history is popped.
+window.addEventListener('popstate', notifyObservers);
+
+// Notify the active element before unload.
+window.addEventListener('beforeunload', () => {
+ if (currentRouteElement) {
+ (/** @type {{onRouteUnload: Function}} */ (currentRouteElement))
+ .onRouteUnload();
}
+});
- /** @type {!Set<!PolymerElement>} */
- const routeObservers = new Set();
+export function navigateToNextStep() {
+ history.pushState(
+ {
+ route: history.state.route,
+ step: history.state.step + 1,
+ },
+ '', `/${history.state.route}`);
+ notifyObservers();
+}
- /** @type {?PolymerElement} */
- let currentRouteElement;
+/**
+ * @param {!Routes} route
+ * @param {number} step
+ */
+export function navigateTo(route, step) {
+ assert([
+ Routes.LANDING,
+ Routes.NEW_USER,
+ Routes.RETURNING_USER,
+ ].includes(route));
+
+ history.pushState(
+ {
+ route: route,
+ step: step,
+ },
+ '', '/' + (route === Routes.LANDING ? '' : route));
+ notifyObservers();
+}
- // Notifies all the elements that extended NavigationBehavior.
- function notifyObservers() {
- if (currentRouteElement) {
- (/** @type {{onRouteExit: Function}} */ (currentRouteElement))
- .onRouteExit();
- currentRouteElement = null;
- }
+/**
+ * Elements can override onRoute(Change|Enter|Exit) to handle route changes.
+ * Order of hooks being called:
+ * 1) onRouteExit() on the old route
+ * 2) onRouteChange() on all subscribed routes
+ * 3) onRouteEnter() on the new route
+ *
+ * @polymerBehavior
+ */
+export const NavigationBehavior = {
+ /** @override */
+ attached: function() {
+ assert(!routeObservers.has(this));
+ routeObservers.add(this);
- const route = /** @type {!welcome.Routes} */ (history.state.route);
+ const route = /** @type {!Routes} */ (history.state.route);
const step = history.state.step;
- routeObservers.forEach(observer => {
- (/** @type {{onRouteChange: Function}} */ (observer))
- .onRouteChange(route, step);
-
- // Modules are only attached to DOM if they're for the current route, so
- // as long as the id of an element matches up to the current step, it
- // means that element is for the current route.
- if (observer.id == `step-${step}`) {
- currentRouteElement = observer;
- }
- });
-
- // If currentRouteElement is not null, it means there was a new route.
- if (currentRouteElement) {
- (/** @type {{onRouteEnter: Function}} */ (currentRouteElement))
- .onRouteEnter();
- (/** @type {{updateFocusForA11y: Function}} */ (currentRouteElement))
- .updateFocusForA11y();
- }
- }
- // Notifies all elements when browser history is popped.
- window.addEventListener('popstate', notifyObservers);
+ // history state was set when page loaded, so when the element first
+ // attaches, call the route-change handler to initialize first.
+ this.onRouteChange(route, step);
+
+ // Modules are only attached to DOM if they're for the current route, so
+ // as long as the id of an element matches up to the current step, it
+ // means that element is for the current route.
+ if (this.id == `step-${step}`) {
+ currentRouteElement = this;
+ this.onRouteEnter();
+ this.updateFocusForA11y();
+ }
+ },
- // Notify the active element before unload.
- window.addEventListener('beforeunload', () => {
- if (currentRouteElement) {
- (/** @type {{onRouteUnload: Function}} */ (currentRouteElement))
- .onRouteUnload();
+ /** Called to update focus when progressing through the modules. */
+ updateFocusForA11y: function() {
+ const header = this.$$('h1');
+ if (header) {
+ afterNextRender(this, () => header.focus());
}
- });
+ },
- function navigateToNextStep() {
- history.pushState(
- {
- route: history.state.route,
- step: history.state.step + 1,
- },
- '', `/${history.state.route}`);
- notifyObservers();
- }
+ /** @override */
+ detached: function() {
+ assert(routeObservers.delete(this));
+ },
/**
- * @param {!welcome.Routes} route
+ * @param {!Routes} route
* @param {number} step
*/
- function navigateTo(route, step) {
- assert([
- Routes.LANDING,
- Routes.NEW_USER,
- Routes.RETURNING_USER,
- ].includes(route));
-
- history.pushState(
- {
- route: route,
- step: step,
- },
- '', '/' + (route === Routes.LANDING ? '' : route));
- notifyObservers();
- }
+ onRouteChange: function(route, step) {},
- /**
- * Elements can override onRoute(Change|Enter|Exit) to handle route changes.
- * Order of hooks being called:
- * 1) onRouteExit() on the old route
- * 2) onRouteChange() on all subscribed routes
- * 3) onRouteEnter() on the new route
- *
- * @polymerBehavior
- */
- const NavigationBehavior = {
- /** @override */
- attached: function() {
- assert(!routeObservers.has(this));
- routeObservers.add(this);
-
- const route = /** @type {!welcome.Routes} */ (history.state.route);
- const step = history.state.step;
-
- // history state was set when page loaded, so when the element first
- // attaches, call the route-change handler to initialize first.
- this.onRouteChange(route, step);
-
- // Modules are only attached to DOM if they're for the current route, so
- // as long as the id of an element matches up to the current step, it
- // means that element is for the current route.
- if (this.id == `step-${step}`) {
- currentRouteElement = this;
- this.onRouteEnter();
- this.updateFocusForA11y();
- }
- },
-
- /** Called to update focus when progressing through the modules. */
- updateFocusForA11y: function() {
- const header = this.$$('h1');
- if (header) {
- Polymer.RenderStatus.afterNextRender(this, () => header.focus());
- }
- },
-
- /** @override */
- detached: function() {
- assert(routeObservers.delete(this));
- },
-
- /**
- * @param {!welcome.Routes} route
- * @param {number} step
- */
- onRouteChange: function(route, step) {},
-
- onRouteEnter: function() {},
-
- onRouteExit: function() {},
-
- onRouteUnload: function() {},
- };
-
- return {
- NavigationBehavior: NavigationBehavior,
- navigateTo: navigateTo,
- navigateToNextStep: navigateToNextStep,
- Routes: Routes,
- };
-});
+ onRouteEnter: function() {},
+
+ onRouteExit: function() {},
+
+ onRouteUnload: function() {},
+};
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn b/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn
index 32399f99cf3..09daeacfd15 100644
--- a/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn
+++ b/chromium/chrome/browser/resources/welcome/ntp_background/BUILD.gn
@@ -3,8 +3,13 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
-
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/welcome/",
+ "js_module_root=gen/chrome/browser/resources/welcome/",
+ ]
deps = [
":ntp_background_metrics_proxy",
":ntp_background_proxy",
@@ -12,27 +17,36 @@ js_type_check("closure_compile") {
]
}
-js_library("nux_ntp_background") {
+js_library("ntp_background_proxy") {
deps = [
":ntp_background_metrics_proxy",
- ":ntp_background_proxy",
- "../:navigation_behavior",
- "../shared:nux_types",
- "//ui/webui/resources/js:cr",
- "//ui/webui/resources/js:i18n_behavior",
- "//ui/webui/resources/js:util",
+ "//ui/webui/resources/js:cr.m",
]
+ externs_list = [ "$externs_path/chrome_send.js" ]
}
-js_library("ntp_background_proxy") {
+js_library("ntp_background_metrics_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "../shared:module_metrics_proxy",
+ "//ui/webui/resources/js:cr.m",
]
- externs_list = [ "$externs_path/chrome_send.js" ]
}
-js_library("ntp_background_metrics_proxy") {
+polymer_modulizer("nux_ntp_background") {
+ js_file = "nux_ntp_background.js"
+ html_file = "nux_ntp_background.html"
+ html_type = "v3-ready"
+}
+
+js_library("nux_ntp_background") {
deps = [
- "../shared:module_metrics_proxy",
+ ":ntp_background_metrics_proxy",
+ ":ntp_background_proxy",
+ "../:navigation_behavior",
+ "../shared:nux_types",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:cr.m",
+ "//ui/webui/resources/js:i18n_behavior.m",
+ "//ui/webui/resources/js:util.m",
]
}
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.html b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.html
deleted file mode 100644
index a5bbfe09db6..00000000000
--- a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="../shared/module_metrics_proxy.html">
-<script src="ntp_background_metrics_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.js b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.js
index dcdb0ffe959..114e5610e9b 100644
--- a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_metrics_proxy.js
@@ -2,22 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
- class NtpBackgroundMetricsProxyImpl extends welcome.ModuleMetricsProxyImpl {
- constructor() {
- super(
- 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
- welcome.NuxNtpBackgroundInteractions);
- }
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+import {ModuleMetricsProxyImpl, NuxNtpBackgroundInteractions} from '../shared/module_metrics_proxy.js';
- getInteractions() {
- return this.interactions_;
- }
+export class NtpBackgroundMetricsProxyImpl extends ModuleMetricsProxyImpl {
+ constructor() {
+ super(
+ 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
+ NuxNtpBackgroundInteractions);
}
- cr.addSingletonGetter(NtpBackgroundMetricsProxyImpl);
+ getInteractions() {
+ return this.interactions_;
+ }
+}
- return {
- NtpBackgroundMetricsProxyImpl: NtpBackgroundMetricsProxyImpl,
- };
-});
+addSingletonGetter(NtpBackgroundMetricsProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.html b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.html
deleted file mode 100644
index a15c5167582..00000000000
--- a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="ntp_background_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.js b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.js
index 17b8ee697bd..6f86f160d4b 100644
--- a/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/ntp_background/ntp_background_proxy.js
@@ -2,100 +2,96 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {NtpBackgroundMetricsProxyImpl} from './ntp_background_metrics_proxy.js';
+
+/**
+ * @typedef {{
+ * id: number,
+ * imageUrl: string,
+ * thumbnailClass: string,
+ * title: string,
+ * }}
+ */
+export let NtpBackgroundData;
+
+/** @interface */
+export class NtpBackgroundProxy {
+ /** @return {!Promise} */
+ clearBackground() {}
+
+ /** @return {!Promise<!Array<!NtpBackgroundData>>} */
+ getBackgrounds() {}
+
/**
- * @typedef {{
- * id: number,
- * imageUrl: string,
- * thumbnailClass: string,
- * title: string,
- * }}
+ * @param {string} url
+ * @return {!Promise<void>}
*/
- let NtpBackgroundData;
+ preloadImage(url) {}
+
+ recordBackgroundImageFailedToLoad() {}
- /** @interface */
- class NtpBackgroundProxy {
- clearBackground() {}
+ /** @param {number} loadTime */
+ recordBackgroundImageLoadTime(loadTime) {}
- /** @return {!Promise<!Array<!welcome.NtpBackgroundData>>} */
- getBackgrounds() {}
+ recordBackgroundImageNeverLoaded() {}
- /**
- * @param {string} url
- * @return {!Promise<void>}
- */
- preloadImage(url) {}
+ /** @param {number} id */
+ setBackground(id) {}
+}
+
+/** @implements {NtpBackgroundProxy} */
+export class NtpBackgroundProxyImpl {
+ /** @override */
+ clearBackground() {
+ return sendWithPromise('clearBackground');
+ }
- recordBackgroundImageFailedToLoad() {}
+ /** @override */
+ getBackgrounds() {
+ return sendWithPromise('getBackgrounds');
+ }
- /** @param {number} loadTime */
- recordBackgroundImageLoadTime(loadTime) {}
+ /** @override */
+ preloadImage(url) {
+ return new Promise((resolve, reject) => {
+ const preloadedImage = new Image();
+ preloadedImage.onerror = reject;
+ preloadedImage.onload = resolve;
+ preloadedImage.src = url;
+ });
+ }
- recordBackgroundImageNeverLoaded() {}
+ /** @override */
+ recordBackgroundImageFailedToLoad() {
+ const ntpInteractions =
+ NtpBackgroundMetricsProxyImpl.getInstance().getInteractions();
+ chrome.metricsPrivate.recordEnumerationValue(
+ 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
+ ntpInteractions.BackgroundImageFailedToLoad,
+ Object.keys(ntpInteractions).length);
+ }
- /** @param {number} id */
- setBackground(id) {}
+ /** @override */
+ recordBackgroundImageLoadTime(loadTime) {
+ chrome.metricsPrivate.recordTime(
+ 'FirstRun.NewUserExperience.NtpBackgroundLoadTime', loadTime);
}
- /** @implements {welcome.NtpBackgroundProxy} */
- class NtpBackgroundProxyImpl {
- /** @override */
- clearBackground() {
- return cr.sendWithPromise('clearBackground');
- }
-
- /** @override */
- getBackgrounds() {
- return cr.sendWithPromise('getBackgrounds');
- }
-
- /** @override */
- preloadImage(url) {
- return new Promise((resolve, reject) => {
- const preloadedImage = new Image();
- preloadedImage.onerror = reject;
- preloadedImage.onload = resolve;
- preloadedImage.src = url;
- });
- }
-
- /** @override */
- recordBackgroundImageFailedToLoad() {
- const ntpInteractions =
- welcome.NtpBackgroundMetricsProxyImpl.getInstance().getInteractions();
- chrome.metricsPrivate.recordEnumerationValue(
- 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
- ntpInteractions.BackgroundImageFailedToLoad,
- Object.keys(ntpInteractions).length);
- }
-
- /** @override */
- recordBackgroundImageLoadTime(loadTime) {
- chrome.metricsPrivate.recordTime(
- 'FirstRun.NewUserExperience.NtpBackgroundLoadTime', loadTime);
- }
-
- /** @override */
- recordBackgroundImageNeverLoaded() {
- const ntpInteractions =
- welcome.NtpBackgroundMetricsProxyImpl.getInstance().getInteractions();
- chrome.metricsPrivate.recordEnumerationValue(
- 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
- ntpInteractions.BackgroundImageNeverLoaded,
- Object.keys(ntpInteractions).length);
- }
-
- /** @override */
- setBackground(id) {
- chrome.send('setBackground', [id]);
- }
+ /** @override */
+ recordBackgroundImageNeverLoaded() {
+ const ntpInteractions =
+ NtpBackgroundMetricsProxyImpl.getInstance().getInteractions();
+ chrome.metricsPrivate.recordEnumerationValue(
+ 'FirstRun.NewUserExperience.NtpBackgroundInteraction',
+ ntpInteractions.BackgroundImageNeverLoaded,
+ Object.keys(ntpInteractions).length);
}
- cr.addSingletonGetter(NtpBackgroundProxyImpl);
+ /** @override */
+ setBackground(id) {
+ chrome.send('setBackground', [id]);
+ }
+}
- return {
- NtpBackgroundData: NtpBackgroundData,
- NtpBackgroundProxy: NtpBackgroundProxy,
- NtpBackgroundProxyImpl: NtpBackgroundProxyImpl,
- };
-});
+addSingletonGetter(NtpBackgroundProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
index c6d03b9a488..f5b6ac423ee 100644
--- a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
+++ b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.html
@@ -1,213 +1,190 @@
-<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/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/util.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="../navigation_behavior.html">
-<link rel="import" href="../shared/animations_css.html">
-<link rel="import" href="../shared/chooser_shared_css.html">
-<link rel="import" href="../shared/i18n_setup.html">
-<link rel="import" href="../shared/step_indicator.html">
-<link rel="import" href="ntp_background_metrics_proxy.html">
-<link rel="import" href="ntp_background_proxy.html">
-
-<dom-module id="nux-ntp-background">
- <template>
- <style include="animations chooser-shared-css">
- :host {
- text-align: center;
- }
-
- #backgroundPreview {
- background-position: center center;
- background-repeat: no-repeat;
- background-size: cover;
- bottom: 0;
- left: 0;
- opacity: 0;
- position: fixed;
- right: 0;
- top: 0;
- transition: background 300ms, opacity 400ms;
- }
-
- #backgroundPreview.active {
- opacity: 1;
- }
-
- #backgroundPreview::before {
- /* Copied from browser/resources/local_ntp/custom_backgrounds.js */
- background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .3));
- /* Pseudo element needs some content (even an empty string) to be
- * displayed. */
- content: '';
- display: block;
- height: 100%;
- width: 100%;
- }
-
- .content {
- /* Put a non-static position on the content so that it can have a
- * higher stacking level than its previous sibling,
- * the #backgroundPreview element. */
- position: relative;
- }
-
- .ntp-background-logo {
- content: url(../images/module_icons/wallpaper_light.svg);
- height: 39px;
- margin: auto;
- margin-bottom: 16px;
- width: 44px;
- }
-
- @media (prefers-color-scheme: dark) {
- .ntp-background-logo {
- content: url(../images/module_icons/wallpaper_dark.svg);
- }
- }
-
- h1 {
- color: var(--cr-primary-text-color);
- font-size: 1.5rem;
- font-weight: 500;
- margin: 0;
- margin-bottom: 46px;
- outline: none;
- transition: color 400ms;
- }
-
- #backgroundPreview.active + .content h1 {
- color: white;
- }
-
- .ntp-backgrounds-grid {
- display: grid;
- grid-gap: 32px;
- grid-template-columns: repeat(3, 176px);
- grid-template-rows: repeat(2, 176px);
- width: 592px;
- }
-
- .option {
- align-items: stretch;
- border-radius: 4px;
- display: flex;
- height: 100%;
- overflow: hidden;
- padding: 0;
- text-align: start;
- transition: border-color 400ms, box-shadow 500ms;
- width: 100%;
- }
-
- #backgroundPreview.active + .content .option {
- border-color: var(--google-grey-refresh-700);
- }
-
- /* Remove outline when button is focused using the mouse. */
- .option:focus:not(.keyboard-focused) {
- outline: none;
- }
-
- .ntp-background-thumbnail {
- background-color: var(--cr-card-background-color);
- background-position: center center;
- background-repeat: no-repeat;
- background-size: cover;
- flex: 1;
- }
-
- .option-name {
- border-top: var(--cr-separator-line);
- color: var(--navi-wallpaper-text-color);
- height: 3rem;
- line-height: 3rem;
- overflow: hidden;
- padding: 0 .75rem;
- text-overflow: ellipsis;
- }
-
- .option[active] .option-name {
- background: var(--cr-checked-color);
- color: var(--cr-card-background-color);
- }
-
- .button-bar {
- margin-top: 56px;
- }
-
- #skipButton {
- background-color: var(--cr-card-background-color)
- }
-
- #skipButton:hover {
- background-image:
- linear-gradient(var(--hover-bg-color), var(--hover-bg-color));
- }
-
- /* Wallpaper Thumbnails */
- .art {
- background-image: url(../images/ntp_thumbnails/art.jpg);
- }
-
- .cityscape {
- background-image: url(../images/ntp_thumbnails/cityscape.jpg);
- }
-
- .earth {
- background-image: url(../images/ntp_thumbnails/earth.jpg);
- }
-
- .geometric-shapes {
- background-image: url(../images/ntp_thumbnails/geometric_shapes.jpg);
- }
-
- .landscape {
- background-image: url(../images/ntp_thumbnails/landscape.jpg);
- }
- </style>
- <div
- id="backgroundPreview"
- on-transitionend="onBackgroundPreviewTransitionEnd_">
- </div>
-
- <div class="content">
- <div class="ntp-background-logo"></div>
- <h1 tabindex="-1">$i18n{ntpBackgroundDescription}</h1>
-
- <div class="ntp-backgrounds-grid slide-in">
- <template is="dom-repeat" items="[[backgrounds_]]">
- <button
- active$="[[isSelectedBackground_(item, selectedBackground_)]]"
- class="option"
- on-click="onBackgroundClick_"
- on-keyup="onBackgroundKeyUp_"
- on-pointerdown="onBackgroundPointerDown_">
- <div
- class$="ntp-background-thumbnail [[item.thumbnailClass]]">
- </div>
- <div class="option-name">[[item.title]]</div>
- </button>
- </template>
- </div>
-
- <div class="button-bar">
- <cr-button id="skipButton" on-click="onSkipClicked_">
- $i18n{skip}
- </cr-button>
- <step-indicator model="[[indicatorModel]]"></step-indicator>
- <cr-button class="action-button" on-click="onNextClicked_">
- $i18n{next}
- <iron-icon icon="cr:chevron-right"></iron-icon>
- </cr-button>
- </div>
- </div>
- </template>
-
- <script src="nux_ntp_background.js"></script>
-</dom-module>
+<style include="animations chooser-shared-css">
+ :host {
+ text-align: center;
+ }
+
+ #backgroundPreview {
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ bottom: 0;
+ left: 0;
+ opacity: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+ transition: background 300ms, opacity 400ms;
+ }
+
+ #backgroundPreview.active {
+ opacity: 1;
+ }
+
+ #backgroundPreview::before {
+ /* Copied from browser/resources/local_ntp/custom_backgrounds.js */
+ background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .3));
+ /* Pseudo element needs some content (even an empty string) to be
+ * displayed. */
+ content: '';
+ display: block;
+ height: 100%;
+ width: 100%;
+ }
+
+ .content {
+ /* Put a non-static position on the content so that it can have a
+ * higher stacking level than its previous sibling,
+ * the #backgroundPreview element. */
+ position: relative;
+ }
+
+ .ntp-background-logo {
+ content: url(../images/module_icons/wallpaper_light.svg);
+ height: 39px;
+ margin: auto;
+ margin-bottom: 16px;
+ width: 44px;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .ntp-background-logo {
+ content: url(../images/module_icons/wallpaper_dark.svg);
+ }
+ }
+
+ h1 {
+ color: var(--cr-primary-text-color);
+ font-size: 1.5rem;
+ font-weight: 500;
+ margin: 0;
+ margin-bottom: 46px;
+ outline: none;
+ transition: color 400ms;
+ }
+
+ #backgroundPreview.active + .content h1 {
+ color: white;
+ }
+
+ .ntp-backgrounds-grid {
+ display: grid;
+ grid-gap: 32px;
+ grid-template-columns: repeat(3, 176px);
+ grid-template-rows: repeat(2, 176px);
+ width: 592px;
+ }
+
+ .option {
+ align-items: stretch;
+ border-radius: 4px;
+ display: flex;
+ height: 100%;
+ overflow: hidden;
+ padding: 0;
+ text-align: start;
+ transition: border-color 400ms, box-shadow 500ms;
+ width: 100%;
+ }
+
+ #backgroundPreview.active + .content .option {
+ border-color: var(--google-grey-refresh-700);
+ }
+
+ /* Remove outline when button is focused using the mouse. */
+ .option:focus:not(.keyboard-focused) {
+ outline: none;
+ }
+
+ .ntp-background-thumbnail {
+ background-color: var(--cr-card-background-color);
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ flex: 1;
+ }
+
+ .option-name {
+ border-top: var(--cr-separator-line);
+ color: var(--navi-wallpaper-text-color);
+ height: 3rem;
+ line-height: 3rem;
+ overflow: hidden;
+ padding: 0 .75rem;
+ text-overflow: ellipsis;
+ }
+
+ .option[active] .option-name {
+ background: var(--cr-checked-color);
+ color: var(--cr-card-background-color);
+ }
+
+ .button-bar {
+ margin-top: 56px;
+ }
+
+ #skipButton {
+ background-color: var(--cr-card-background-color)
+ }
+
+ #skipButton:hover {
+ background-image:
+ linear-gradient(var(--hover-bg-color), var(--hover-bg-color));
+ }
+
+ /* Wallpaper Thumbnails */
+ .art {
+ background-image: url(../images/ntp_thumbnails/art.jpg);
+ }
+
+ .cityscape {
+ background-image: url(../images/ntp_thumbnails/cityscape.jpg);
+ }
+
+ .earth {
+ background-image: url(../images/ntp_thumbnails/earth.jpg);
+ }
+
+ .geometric-shapes {
+ background-image: url(../images/ntp_thumbnails/geometric_shapes.jpg);
+ }
+
+ .landscape {
+ background-image: url(../images/ntp_thumbnails/landscape.jpg);
+ }
+</style>
+<div
+ id="backgroundPreview"
+ on-transitionend="onBackgroundPreviewTransitionEnd_">
+</div>
+
+<div class="content">
+ <div class="ntp-background-logo"></div>
+ <h1 tabindex="-1">$i18n{ntpBackgroundDescription}</h1>
+
+ <div class="ntp-backgrounds-grid slide-in">
+ <template is="dom-repeat" items="[[backgrounds_]]">
+ <button
+ active$="[[isSelectedBackground_(item, selectedBackground_)]]"
+ class="option"
+ on-click="onBackgroundClick_"
+ on-keyup="onBackgroundKeyUp_"
+ on-pointerdown="onBackgroundPointerDown_">
+ <div
+ class$="ntp-background-thumbnail [[item.thumbnailClass]]">
+ </div>
+ <div class="option-name">[[item.title]]</div>
+ </button>
+ </template>
+ </div>
+
+ <div class="button-bar">
+ <cr-button id="skipButton" on-click="onSkipClicked_">
+ $i18n{skip}
+ </cr-button>
+ <step-indicator model="[[indicatorModel]]"></step-indicator>
+ <cr-button class="action-button" on-click="onNextClicked_">
+ $i18n{next}
+ <iron-icon icon="cr:chevron-right"></iron-icon>
+ </cr-button>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js
index 1af8a41fe97..b255441592f 100644
--- a/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js
+++ b/chromium/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js
@@ -2,28 +2,51 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/js/cr.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../shared/animations_css.js';
+import '../shared/chooser_shared_css.js';
+import '../shared/step_indicator.js';
+import '../strings.m.js';
+
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {isRTL} from 'chrome://resources/js/util.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from '../navigation_behavior.js';
+import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
+import {stepIndicatorModel} from '../shared/nux_types.js';
+
+import {NtpBackgroundMetricsProxyImpl} from './ntp_background_metrics_proxy.js';
+import {NtpBackgroundData, NtpBackgroundProxy, NtpBackgroundProxyImpl} from './ntp_background_proxy.js';
+
const KEYBOARD_FOCUSED_CLASS = 'keyboard-focused';
Polymer({
is: 'nux-ntp-background',
+ _template: html`{__html_template__}`,
+
behaviors: [
I18nBehavior,
- welcome.NavigationBehavior,
+ NavigationBehavior,
],
properties: {
- /** @type {welcome.stepIndicatorModel} */
+ /** @type {stepIndicatorModel} */
indicatorModel: Object,
- /** @private {?welcome.NtpBackgroundData} */
+ /** @private {?NtpBackgroundData} */
selectedBackground_: {
observer: 'onSelectedBackgroundChange_',
type: Object,
},
},
- /** @private {?Array<!welcome.NtpBackgroundData>} */
+ /** @private {?Array<!NtpBackgroundData>} */
backgrounds_: null,
/** @private */
@@ -32,17 +55,17 @@ Polymer({
/** @private {boolean} */
imageIsLoading_: false,
- /** @private {?welcome.ModuleMetricsManager} */
+ /** @private {?ModuleMetricsManager} */
metricsManager_: null,
- /** @private {?welcome.NtpBackgroundProxy} */
+ /** @private {?NtpBackgroundProxy} */
ntpBackgroundProxy_: null,
/** @override */
ready: function() {
- this.ntpBackgroundProxy_ = welcome.NtpBackgroundProxyImpl.getInstance();
- this.metricsManager_ = new welcome.ModuleMetricsManager(
- welcome.NtpBackgroundMetricsProxyImpl.getInstance());
+ this.ntpBackgroundProxy_ = NtpBackgroundProxyImpl.getInstance();
+ this.metricsManager_ =
+ new ModuleMetricsManager(NtpBackgroundMetricsProxyImpl.getInstance());
},
onRouteEnter: function() {
@@ -98,7 +121,7 @@ Polymer({
},
/**
- * @param {!welcome.NtpBackgroundData} background
+ * @param {!NtpBackgroundData} background
* @private
*/
isSelectedBackground_: function(background) {
@@ -144,7 +167,7 @@ Polymer({
},
/**
- * @param {!{model: !{item: !welcome.NtpBackgroundData}}} e
+ * @param {!{model: !{item: !NtpBackgroundData}}} e
* @private
*/
onBackgroundClick_: function(e) {
@@ -217,14 +240,14 @@ Polymer({
this.ntpBackgroundProxy_.clearBackground();
}
this.metricsManager_.recordGetStarted();
- welcome.navigateToNextStep();
+ navigateToNextStep();
},
/** @private */
onSkipClicked_: function() {
this.finalized_ = true;
this.metricsManager_.recordNoThanks();
- welcome.navigateToNextStep();
+ navigateToNextStep();
if (this.hasValidSelectedBackground_()) {
this.fire('iron-announce', {text: this.i18n('ntpBackgroundReset')});
diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn b/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn
index e633bc817e4..0c82491a12e 100644
--- a/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn
+++ b/chromium/chrome/browser/resources/welcome/set_as_default/BUILD.gn
@@ -3,8 +3,14 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/welcome/",
+ "js_module_root=gen/chrome/browser/resources/welcome/",
+ ]
deps = [
":nux_set_as_default",
]
@@ -15,18 +21,21 @@ js_library("nux_set_as_default") {
":nux_set_as_default_proxy",
"../:navigation_behavior",
"../shared:nux_types",
- "//ui/webui/resources/js:load_time_data",
- "//ui/webui/resources/js:web_ui_listener_behavior",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
js_library("nux_set_as_default_proxy") {
deps = [
- "../shared:nux_types",
- "//ui/webui/resources/js:cr",
- ]
- externs_list = [
- "$externs_path/chrome_send.js",
- "$externs_path/metrics_private.js",
+ "//ui/webui/resources/js:cr.m",
]
+ externs_list = [ "$externs_path/metrics_private.js" ]
+}
+
+polymer_modulizer("nux_set_as_default") {
+ js_file = "nux_set_as_default.js"
+ html_file = "nux_set_as_default.html"
+ html_type = "v3-ready"
}
diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html
index 53688f8c549..c7f2b065ef4 100644
--- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html
+++ b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html
@@ -1,104 +1,84 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="animations">
+ .container {
+ text-align: center;
+ }
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="../navigation_behavior.html">
-<link rel="import" href="../shared/animations_css.html">
-<link rel="import" href="../shared/i18n_setup.html">
-<link rel="import" href="../shared/step_indicator.html">
-<link rel="import" href="nux_set_as_default_proxy.html">
-<if expr="is_win">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-</if>
-
-<dom-module id="nux-set-as-default">
- <template>
- <style include="animations">
- .container {
- text-align: center;
- }
-
- .logo {
- content: url(../images/module_icons/set_default_light.svg);
- display: inline-block;
- height: 38px;
- margin-bottom: 16px;
- width: 42px;
- }
+ .logo {
+ content: url(../images/module_icons/set_default_light.svg);
+ display: inline-block;
+ height: 38px;
+ margin-bottom: 16px;
+ width: 42px;
+ }
- @media (prefers-color-scheme: dark) {
- .logo {
- content: url(../images/module_icons/set_default_dark.svg);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ .logo {
+ content: url(../images/module_icons/set_default_dark.svg);
+ }
+ }
- .illustration {
- content: url(../images/set_default_light.svg);
- margin: auto;
- width: 454px;
- }
+ .illustration {
+ content: url(../images/set_default_light.svg);
+ margin: auto;
+ width: 454px;
+ }
- @media (prefers-color-scheme: dark) {
- .illustration {
- content: url(../images/set_default_dark.svg);
- }
- }
+ @media (prefers-color-scheme: dark) {
+ .illustration {
+ content: url(../images/set_default_dark.svg);
+ }
+ }
- h1 {
- color: var(--cr-primary-text-color);
- font-size: 1.5rem;
- font-weight: 500;
- line-height: 2.5rem;
- margin: 0;
- outline: none;
- }
+ h1 {
+ color: var(--cr-primary-text-color);
+ font-size: 1.5rem;
+ font-weight: 500;
+ line-height: 2.5rem;
+ margin: 0;
+ outline: none;
+ }
- h2 {
- color: var(--cr-secondary-text-color);
- font-size: 1.25rem;
- font-weight: unset;
- line-height: 1.875rem;
- margin: auto;
- margin-bottom: 48px;
- margin-top: 16px;
- max-width: 400px;
- }
+ h2 {
+ color: var(--cr-secondary-text-color);
+ font-size: 1.25rem;
+ font-weight: unset;
+ line-height: 1.875rem;
+ margin: auto;
+ margin-bottom: 48px;
+ margin-top: 16px;
+ max-width: 400px;
+ }
- .button-bar {
- display: flex;
- justify-content: space-between;
- margin-top: 64px;
- }
+ .button-bar {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 64px;
+ }
<if expr="is_win">
- iron-icon[icon='cr:open-in-new'] {
- height: 20px;
- margin-inline-start: 6px;
- margin-inline-end: -10px;
- width: 20px;
- }
+ iron-icon[icon='cr:open-in-new'] {
+ height: 20px;
+ margin-inline-start: 6px;
+ margin-inline-end: -10px;
+ width: 20px;
+ }
</if>
- </style>
- <div class="container">
- <div class="logo"></div>
- <h1 tabindex="-1">$i18n{setDefaultHeader}</h1>
- <h2>$i18n{setDefaultSubHeader}</h2>
- <div class="illustration slide-in" aria-hidden="true"></div>
- <div class="button-bar">
- <cr-button id="decline-button" on-click="onDeclineClick_">
- $i18n{skip}
- </cr-button>
- <step-indicator model="[[indicatorModel]]"></step-indicator>
- <cr-button class="action-button" on-click="onSetDefaultClick_">
- $i18n{setDefaultConfirm}
+</style>
+<div class="container">
+ <div class="logo"></div>
+ <h1 tabindex="-1">$i18n{setDefaultHeader}</h1>
+ <h2>$i18n{setDefaultSubHeader}</h2>
+ <div class="illustration slide-in" aria-hidden="true"></div>
+ <div class="button-bar">
+ <cr-button id="decline-button" on-click="onDeclineClick_">
+ $i18n{skip}
+ </cr-button>
+ <step-indicator model="[[indicatorModel]]"></step-indicator>
+ <cr-button class="action-button" on-click="onSetDefaultClick_">
+ $i18n{setDefaultConfirm}
<if expr="is_win">
- <iron-icon icon="cr:open-in-new" hidden="[[!isWin10]]"></iron-icon>
+ <iron-icon icon="cr:open-in-new" hidden="[[!isWin10]]"></iron-icon>
</if>
- </cr-button>
- </div>
- </div>
- </template>
- <script src="nux_set_as_default.js"></script>
-</dom-module>
+ </cr-button>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js
index 37e69a2de97..c2be7a3c5ee 100644
--- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js
+++ b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js
@@ -2,16 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+// <if expr="is_win">
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+// </if>
+import '../shared/animations_css.js';
+import '../shared/step_indicator.js';
+import '../strings.m.js';
+
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from '../navigation_behavior.js';
+import {DefaultBrowserInfo, stepIndicatorModel} from '../shared/nux_types.js';
+
+import {NuxSetAsDefaultProxy, NuxSetAsDefaultProxyImpl} from './nux_set_as_default_proxy.js';
+
Polymer({
is: 'nux-set-as-default',
+ _template: html`{__html_template__}`,
+
behaviors: [
WebUIListenerBehavior,
- welcome.NavigationBehavior,
+ NavigationBehavior,
],
properties: {
- /** @type {welcome.stepIndicatorModel} */
+ /** @type {stepIndicatorModel} */
indicatorModel: Object,
// <if expr="is_win">
@@ -22,15 +43,18 @@ Polymer({
// </if>
},
- /** @private {welcome.NuxSetAsDefaultProxy} */
+ /** @private {NuxSetAsDefaultProxy} */
browserProxy_: null,
/** @private {boolean} */
finalized_: false,
+ /** @private {!Function} */
+ navigateToNextStep_: navigateToNextStep,
+
/** @override */
ready: function() {
- this.browserProxy_ = welcome.NuxSetAsDefaultProxyImpl.getInstance();
+ this.browserProxy_ = NuxSetAsDefaultProxyImpl.getInstance();
this.addWebUIListener(
'browser-default-state-changed',
@@ -80,7 +104,7 @@ Polymer({
/**
* Automatically navigate to the next onboarding step once default changed.
- * @param {!welcome.DefaultBrowserInfo} status
+ * @param {!DefaultBrowserInfo} status
* @private
*/
onDefaultBrowserChange_: function(status) {
@@ -105,7 +129,6 @@ Polymer({
/** @private */
finished_: function() {
this.finalized_ = true;
-
- welcome.navigateToNextStep();
+ this.navigateToNextStep_();
},
});
diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.html b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.html
deleted file mode 100644
index b1dcbde23a5..00000000000
--- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="nux_set_as_default_proxy.js"></script> \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.js b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.js
index e7668ffa467..33266dac325 100644
--- a/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/set_as_default/nux_set_as_default_proxy.js
@@ -2,100 +2,95 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
- const NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME =
- 'FirstRun.NewUserExperience.SetAsDefaultInteraction';
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {DefaultBrowserInfo} from '../shared/nux_types.js';
- /**
- * NuxSetAsDefaultInteractions enum.
- * These values are persisted to logs and should not be renumbered or re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
- */
- const NuxSetAsDefaultInteractions = {
- PageShown: 0,
- NavigatedAway: 1,
- Skip: 2,
- ClickSetDefault: 3,
- SuccessfullySetDefault: 4,
- NavigatedAwayThroughBrowserHistory: 5,
- };
+const NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME =
+ 'FirstRun.NewUserExperience.SetAsDefaultInteraction';
- const NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT =
- Object.keys(NuxSetAsDefaultInteractions).length;
+/**
+ * NuxSetAsDefaultInteractions enum.
+ * These values are persisted to logs and should not be renumbered or re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+const NuxSetAsDefaultInteractions = {
+ PageShown: 0,
+ NavigatedAway: 1,
+ Skip: 2,
+ ClickSetDefault: 3,
+ SuccessfullySetDefault: 4,
+ NavigatedAwayThroughBrowserHistory: 5,
+};
- /** @interface */
- class NuxSetAsDefaultProxy {
- /** @return {!Promise<!welcome.DefaultBrowserInfo>} */
- requestDefaultBrowserState() {}
- setAsDefault() {}
- recordPageShown() {}
- recordNavigatedAway() {}
- recordNavigatedAwayThroughBrowserHistory() {}
- recordSkip() {}
- recordBeginSetDefault() {}
- recordSuccessfullySetDefault() {}
- }
+const NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT =
+ Object.keys(NuxSetAsDefaultInteractions).length;
- /** @implements {welcome.NuxSetAsDefaultProxy} */
- class NuxSetAsDefaultProxyImpl {
- /** @override */
- requestDefaultBrowserState() {
- return cr.sendWithPromise('requestDefaultBrowserState');
- }
+/** @interface */
+export class NuxSetAsDefaultProxy {
+ /** @return {!Promise<!DefaultBrowserInfo>} */
+ requestDefaultBrowserState() {}
+ setAsDefault() {}
+ recordPageShown() {}
+ recordNavigatedAway() {}
+ recordNavigatedAwayThroughBrowserHistory() {}
+ recordSkip() {}
+ recordBeginSetDefault() {}
+ recordSuccessfullySetDefault() {}
+}
- /** @override */
- setAsDefault() {
- chrome.send('setAsDefaultBrowser');
- }
+/** @implements {NuxSetAsDefaultProxy} */
+export class NuxSetAsDefaultProxyImpl {
+ /** @override */
+ requestDefaultBrowserState() {
+ return sendWithPromise('requestDefaultBrowserState');
+ }
- /** @override */
- recordPageShown() {
- this.recordInteraction_(NuxSetAsDefaultInteractions.PageShown);
- }
+ /** @override */
+ setAsDefault() {
+ chrome.send('setAsDefaultBrowser');
+ }
- /** @override */
- recordNavigatedAway() {
- this.recordInteraction_(NuxSetAsDefaultInteractions.NavigatedAway);
- }
+ /** @override */
+ recordPageShown() {
+ this.recordInteraction_(NuxSetAsDefaultInteractions.PageShown);
+ }
- /** @override */
- recordNavigatedAwayThroughBrowserHistory() {
- this.recordInteraction_(
- NuxSetAsDefaultInteractions.NavigatedAwayThroughBrowserHistory);
- }
+ /** @override */
+ recordNavigatedAway() {
+ this.recordInteraction_(NuxSetAsDefaultInteractions.NavigatedAway);
+ }
- /** @override */
- recordSkip() {
- this.recordInteraction_(NuxSetAsDefaultInteractions.Skip);
- }
+ /** @override */
+ recordNavigatedAwayThroughBrowserHistory() {
+ this.recordInteraction_(
+ NuxSetAsDefaultInteractions.NavigatedAwayThroughBrowserHistory);
+ }
- /** @override */
- recordBeginSetDefault() {
- this.recordInteraction_(NuxSetAsDefaultInteractions.ClickSetDefault);
- }
+ /** @override */
+ recordSkip() {
+ this.recordInteraction_(NuxSetAsDefaultInteractions.Skip);
+ }
- /** @override */
- recordSuccessfullySetDefault() {
- this.recordInteraction_(
- NuxSetAsDefaultInteractions.SuccessfullySetDefault);
- }
+ /** @override */
+ recordBeginSetDefault() {
+ this.recordInteraction_(NuxSetAsDefaultInteractions.ClickSetDefault);
+ }
- /**
- * @param {number} interaction
- * @private
- */
- recordInteraction_(interaction) {
- chrome.metricsPrivate.recordEnumerationValue(
- NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME, interaction,
- NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT);
- }
+ /** @override */
+ recordSuccessfullySetDefault() {
+ this.recordInteraction_(NuxSetAsDefaultInteractions.SuccessfullySetDefault);
}
- cr.addSingletonGetter(NuxSetAsDefaultProxyImpl);
+ /**
+ * @param {number} interaction
+ * @private
+ */
+ recordInteraction_(interaction) {
+ chrome.metricsPrivate.recordEnumerationValue(
+ NUX_SET_AS_DEFAULT_INTERACTION_METRIC_NAME, interaction,
+ NUX_SET_AS_DEFAULT_INTERACTIONS_COUNT);
+ }
+}
- return {
- NuxSetAsDefaultProxy: NuxSetAsDefaultProxy,
- NuxSetAsDefaultProxyImpl: NuxSetAsDefaultProxyImpl,
- };
-});
+addSingletonGetter(NuxSetAsDefaultProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/shared/BUILD.gn b/chromium/chrome/browser/resources/welcome/shared/BUILD.gn
index 9a06f4194e1..9ebc573c885 100644
--- a/chromium/chrome/browser/resources/welcome/shared/BUILD.gn
+++ b/chromium/chrome/browser/resources/welcome/shared/BUILD.gn
@@ -3,8 +3,14 @@
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
js_type_check("closure_compile") {
+ is_polymer3 = true
+ closure_flags = default_closure_args + [
+ "js_module_root=../../chrome/browser/resources/welcome/",
+ "js_module_root=gen/chrome/browser/resources/welcome/",
+ ]
deps = [
":bookmark_proxy",
":module_metrics_proxy",
@@ -15,7 +21,7 @@ js_type_check("closure_compile") {
js_library("bookmark_proxy") {
deps = [
- "//ui/webui/resources/js:cr",
+ "//ui/webui/resources/js:cr.m",
]
externs_list = [
"$externs_path/chrome_extensions.js",
@@ -24,17 +30,69 @@ js_library("bookmark_proxy") {
}
js_library("module_metrics_proxy") {
- deps = [
- "//ui/webui/resources/js:cr",
- ]
externs_list = [ "$externs_path/metrics_private.js" ]
}
js_library("nux_types") {
+}
+
+js_library("step_indicator") {
deps = [
- "//ui/webui/resources/js:cr",
+ ":nux_types",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
-js_library("step_indicator") {
+polymer_modulizer("animations_css") {
+ js_file = "animations_css.js"
+ html_file = "animations_css.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("chooser_shared_css") {
+ js_file = "chooser_shared_css.js"
+ html_file = "chooser_shared_css.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("navi_colors_css") {
+ js_file = "navi_colors_css.js"
+ html_file = "navi_colors_css.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("action_link_style_css") {
+ js_file = "action_link_style_css.js"
+ html_file = "action_link_style_css.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("splash_pages_shared_css") {
+ js_file = "splash_pages_shared_css.js"
+ html_file = "splash_pages_shared_css.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("onboarding_background") {
+ js_file = "onboarding_background.js"
+ html_file = "onboarding_background.html"
+ html_type = "v3-ready"
+}
+
+polymer_modulizer("step_indicator") {
+ js_file = "step_indicator.js"
+ html_file = "step_indicator.html"
+ html_type = "v3-ready"
+}
+
+group("polymer3_elements") {
+ deps = [
+ ":action_link_style_css_module",
+ ":animations_css_module",
+ ":chooser_shared_css_module",
+ ":navi_colors_css_module",
+ ":onboarding_background_module",
+ ":splash_pages_shared_css_module",
+ ":step_indicator_module",
+ ]
}
diff --git a/chromium/chrome/browser/resources/welcome/shared/action_link_style.js b/chromium/chrome/browser/resources/welcome/shared/action_link_style.js
deleted file mode 100644
index b4e52c4ba58..00000000000
--- a/chromium/chrome/browser/resources/welcome/shared/action_link_style.js
+++ /dev/null
@@ -1,9 +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 Initiates focus-outline-manager for this document so that
- * action-link style can take advantage of it.
- */
-cr.ui.FocusOutlineManager.forDocument(document); \ No newline at end of file
diff --git a/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.html b/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.html
index 96d00fb8bcc..90f5c2ce76e 100644
--- a/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.html
+++ b/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.html
@@ -1,34 +1,24 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<template>
+ <style>
+ button.action-link {
+ -webkit-appearance: none;
+ background: none;
+ border: none;
+ color: var(--cr-link-color);
+ cursor: pointer;
+ display: inline-block;
+ font-family: inherit;
+ text-decoration: none;
+ }
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/cr/ui/focus_outline_manager.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
+ button.action-link[disabled] {
+ color: var(--paper-grey-600);
+ cursor: default;
+ opacity: 0.65;
+ }
-<dom-module id="action-link-style">
- <template>
- <style>
- button.action-link {
- -webkit-appearance: none;
- background: none;
- border: none;
- color: var(--cr-link-color);
- cursor: pointer;
- display: inline-block;
- font-family: inherit;
- text-decoration: none;
- }
-
- button.action-link[disabled] {
- color: var(--paper-grey-600);
- cursor: default;
- opacity: 0.65;
- }
-
- :host-context(html:not(.focus-outline-visible)) button.action-link {
- outline: none;
- }
- </style>
- </template>
-</dom-module>
-
-<script src="action_link_style.js"></script>
+ :host-context(html:not(.focus-outline-visible)) button.action-link {
+ outline: none;
+ }
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.js b/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.js
new file mode 100644
index 00000000000..c6259334546
--- /dev/null
+++ b/chromium/chrome/browser/resources/welcome/shared/action_link_style_css.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.
+
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('action-link-style');
+
+// Initiate focus-outline-manager for this document so that action-link style
+// can take advantage of it.
+FocusOutlineManager.forDocument(document);
diff --git a/chromium/chrome/browser/resources/welcome/shared/animations_css.html b/chromium/chrome/browser/resources/welcome/shared/animations_css.html
index c79bd5443f6..268c0300275 100644
--- a/chromium/chrome/browser/resources/welcome/shared/animations_css.html
+++ b/chromium/chrome/browser/resources/welcome/shared/animations_css.html
@@ -1,39 +1,35 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<template>
+ <style>
+ @keyframes fade-in {
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+ }
-<dom-module id="animations">
- <template>
- <style>
- @keyframes fade-in {
- 0% { opacity: 0; }
- 100% { opacity: 1; }
- }
+ @keyframes slide-in {
+ 0% { transform: translateX(var(--slide-in-length, 40px)); }
+ 100% { transform: translateX(0); }
+ }
- @keyframes slide-in {
- 0% { transform: translateX(var(--slide-in-length, 40px)); }
- 100% { transform: translateX(0); }
- }
+ .fade-in {
+ animation-delay: var(--animation-delay, 0);
+ animation-duration: 200ms;
+ animation-fill-mode: forwards;
+ animation-name: fade-in;
+ animation-timing-function: ease-in;
+ opacity: 0;
+ }
- .fade-in {
- animation-delay: var(--animation-delay, 0);
- animation-duration: 200ms;
- animation-fill-mode: forwards;
- animation-name: fade-in;
- animation-timing-function: ease-in;
- opacity: 0;
- }
+ .slide-in {
+ animation-delay: var(--animation-delay, 0);
+ animation-duration: 200ms;
+ animation-fill-mode: forwards;
+ animation-name: slide-in;
+ animation-timing-function: ease;
+ transform: translateX(30px);
+ }
- .slide-in {
- animation-delay: var(--animation-delay, 0);
- animation-duration: 200ms;
- animation-fill-mode: forwards;
- animation-name: slide-in;
- animation-timing-function: ease;
- transform: translateX(30px);
- }
-
- :host-context(html[dir='rtl']) .slide-in {
- --slide-in-length: -40px;
- }
- </style>
- </template>
-</dom-module>
+ :host-context(html[dir='rtl']) .slide-in {
+ --slide-in-length: -40px;
+ }
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/animations_css.js b/chromium/chrome/browser/resources/welcome/shared/animations_css.js
new file mode 100644
index 00000000000..5cdea0a637f
--- /dev/null
+++ b/chromium/chrome/browser/resources/welcome/shared/animations_css.js
@@ -0,0 +1,9 @@
+// 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 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('animations');
diff --git a/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.js b/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.js
index 42bf8060736..c90508462a0 100644
--- a/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/shared/bookmark_proxy.js
@@ -2,91 +2,85 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+
+/**
+ * @typedef {{
+ * parentId: string,
+ * title: string,
+ * url: string,
+ * }}
+ */
+let bookmarkData;
+
+/** @interface */
+export class BookmarkProxy {
/**
- * @typedef {{
- * parentId: string,
- * title: string,
- * url: string,
- * }}
+ * @param {!bookmarkData} data
+ * @param {!Function} callback
*/
- let bookmarkData;
+ addBookmark(data, callback) {}
- /** @interface */
- class BookmarkProxy {
- /**
- * @param {!bookmarkData} data
- * @param {!Function} callback
- */
- addBookmark(data, callback) {}
+ /** @param {string} id ID provided by callback when bookmark was added. */
+ removeBookmark(id) {}
- /** @param {string} id ID provided by callback when bookmark was added. */
- removeBookmark(id) {}
+ /** @param {boolean} show */
+ toggleBookmarkBar(show) {}
- /** @param {boolean} show */
- toggleBookmarkBar(show) {}
+ /** @return {!Promise<boolean>} */
+ isBookmarkBarShown() {}
+}
- /** @return {!Promise<boolean>} */
- isBookmarkBarShown() {}
+/** @implements {BookmarkProxy} */
+export class BookmarkProxyImpl {
+ /** @override */
+ addBookmark(data, callback) {
+ chrome.bookmarks.create(data, callback);
}
- /** @implements {welcome.BookmarkProxy} */
- class BookmarkProxyImpl {
- /** @override */
- addBookmark(data, callback) {
- chrome.bookmarks.create(data, callback);
- }
-
- /** @override */
- removeBookmark(id) {
- chrome.bookmarks.remove(id);
- }
-
- /** @override */
- toggleBookmarkBar(show) {
- chrome.send('toggleBookmarkBar', [show]);
- }
-
- /** @override */
- isBookmarkBarShown() {
- return cr.sendWithPromise('isBookmarkBarShown');
- }
+ /** @override */
+ removeBookmark(id) {
+ chrome.bookmarks.remove(id);
}
- cr.addSingletonGetter(BookmarkProxyImpl);
-
- // Wrapper for bookmark proxy to keep some additional states.
- class BookmarkBarManager {
- constructor() {
- /** @private {welcome.BookmarkProxy} */
- this.proxy_ = BookmarkProxyImpl.getInstance();
-
- /** @private {boolean} */
- this.isBarShown_ = false;
-
- /** @type {!Promise} */
- this.initialized = this.proxy_.isBookmarkBarShown().then(shown => {
- this.isBarShown_ = shown;
- });
- }
-
- /** @return {boolean} */
- getShown() {
- return this.isBarShown_;
- }
-
- /** @param {boolean} show */
- setShown(show) {
- this.isBarShown_ = show;
- this.proxy_.toggleBookmarkBar(show);
- }
+ /** @override */
+ toggleBookmarkBar(show) {
+ chrome.send('toggleBookmarkBar', [show]);
}
- cr.addSingletonGetter(BookmarkBarManager);
+ /** @override */
+ isBookmarkBarShown() {
+ return sendWithPromise('isBookmarkBarShown');
+ }
+}
+
+addSingletonGetter(BookmarkProxyImpl);
+
+// Wrapper for bookmark proxy to keep some additional states.
+export class BookmarkBarManager {
+ constructor() {
+ /** @private {BookmarkProxy} */
+ this.proxy_ = BookmarkProxyImpl.getInstance();
+
+ /** @private {boolean} */
+ this.isBarShown_ = false;
+
+ /** @type {!Promise} */
+ this.initialized = this.proxy_.isBookmarkBarShown().then(shown => {
+ this.isBarShown_ = shown;
+ });
+ }
+
+ /** @return {boolean} */
+ getShown() {
+ return this.isBarShown_;
+ }
+
+ /** @param {boolean} show */
+ setShown(show) {
+ this.isBarShown_ = show;
+ this.proxy_.toggleBookmarkBar(show);
+ }
+}
- return {
- BookmarkProxy: BookmarkProxy,
- BookmarkProxyImpl: BookmarkProxyImpl,
- BookmarkBarManager: BookmarkBarManager,
- };
-});
+addSingletonGetter(BookmarkBarManager);
diff --git a/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.html b/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.html
index 52b75a13193..d7346722deb 100644
--- a/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.html
+++ b/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.html
@@ -1,43 +1,35 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<template>
+ <style include="navi-colors-css">
+ .option {
+ background: var(--cr-card-background-color);
+ border: 1px solid var(--navi-border-color);
+ color: var(--cr-primary-text-color);
+ cursor: pointer;
+ flex-direction: column;
+ }
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
-<link rel="import" href="navi_colors_css.html">
+ .option:hover {
+ box-shadow: var(--navi-option-box-shadow);
+ }
-<dom-module id="chooser-shared-css">
- <template>
- <style include="navi-colors-css">
- .option {
- background: var(--cr-card-background-color);
- border: 1px solid var(--navi-border-color);
- color: var(--cr-primary-text-color);
- cursor: pointer;
- flex-direction: column;
- }
+ .option-name {
+ font-size: .875rem;
+ }
- .option:hover {
- box-shadow: var(--navi-option-box-shadow);
- }
+ .button-bar {
+ display: flex;
+ justify-content: space-between;
+ }
- .option-name {
- font-size: .875rem;
- }
+ :host-context([dir=rtl]) iron-icon[icon='cr:chevron-right'] {
+ transform: scaleX(-1);
+ }
- .button-bar {
- display: flex;
- justify-content: space-between;
- }
-
- :host-context([dir=rtl]) iron-icon[icon='cr:chevron-right'] {
- transform: scaleX(-1);
- }
-
- iron-icon[icon='cr:chevron-right'] {
- height: 1.25rem;
- margin-inline-end: -.625rem;
- margin-inline-start: .375rem;
- width: 1.25rem;
- }
- </style>
- </template>
-</dom-module>
+ iron-icon[icon='cr:chevron-right'] {
+ height: 1.25rem;
+ margin-inline-end: -.625rem;
+ margin-inline-start: .375rem;
+ width: 1.25rem;
+ }
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.js b/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.js
new file mode 100644
index 00000000000..6f2044bc1d3
--- /dev/null
+++ b/chromium/chrome/browser/resources/welcome/shared/chooser_shared_css.js
@@ -0,0 +1,13 @@
+// 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 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/cr_elements/md_select_css.m.js';
+import './navi_colors_css.js';
+
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('chooser-shared-css');
diff --git a/chromium/chrome/browser/resources/welcome/shared/i18n_setup.html b/chromium/chrome/browser/resources/welcome/shared/i18n_setup.html
deleted file mode 100644
index c505b2c1365..00000000000
--- a/chromium/chrome/browser/resources/welcome/shared/i18n_setup.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<script src="chrome://resources/js/load_time_data.js"></script>
-<script src="../strings.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.html b/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.html
deleted file mode 100644
index 5c10f79489a..00000000000
--- a/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="module_metrics_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.js b/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.js
index d6a437b7163..75819f2e515 100644
--- a/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/shared/module_metrics_proxy.js
@@ -2,241 +2,228 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
+/**
+ * NuxNtpBackgroundInteractions enum.
+ * These values are persisted to logs and should not be renumbered or
+ * re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+export const NuxNtpBackgroundInteractions = {
+ PageShown: 0,
+ DidNothingAndNavigatedAway: 1,
+ DidNothingAndChoseSkip: 2,
+ DidNothingAndChoseNext: 3,
+ ChoseAnOptionAndNavigatedAway: 4,
+ ChoseAnOptionAndChoseSkip: 5,
+ ChoseAnOptionAndChoseNext: 6,
+ NavigatedAwayThroughBrowserHistory: 7,
+ BackgroundImageFailedToLoad: 8,
+ BackgroundImageNeverLoaded: 9,
+};
+
+/**
+ * NuxGoogleAppsInteractions enum.
+ * These values are persisted to logs and should not be renumbered or
+ * re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+export const NuxGoogleAppsInteractions = {
+ PageShown: 0,
+ NotUsed_DEPRECATED: 1,
+ GetStarted_DEPRECATED: 2,
+ DidNothingAndNavigatedAway: 3,
+ DidNothingAndChoseSkip: 4,
+ ChoseAnOptionAndNavigatedAway: 5,
+ ChoseAnOptionAndChoseSkip: 6,
+ ChoseAnOptionAndChoseNext: 7,
+ ClickedDisabledNextButtonAndNavigatedAway: 8,
+ ClickedDisabledNextButtonAndChoseSkip: 9,
+ ClickedDisabledNextButtonAndChoseNext: 10,
+ DidNothingAndChoseNext: 11,
+ NavigatedAwayThroughBrowserHistory: 12,
+};
+
+/** @interface */
+class ModuleMetricsProxy {
+ recordPageShown() {}
+
+ recordDidNothingAndNavigatedAway() {}
+
+ recordDidNothingAndChoseSkip() {}
+
+ recordDidNothingAndChoseNext() {}
+
+ recordChoseAnOptionAndNavigatedAway() {}
+
+ recordChoseAnOptionAndChoseSkip() {}
+
+ recordChoseAnOptionAndChoseNext() {}
+
+ recordClickedDisabledNextButtonAndNavigatedAway() {}
+
+ recordClickedDisabledNextButtonAndChoseSkip() {}
+
+ recordClickedDisabledNextButtonAndChoseNext() {}
+
+ recordNavigatedAwayThroughBrowserHistory() {}
+}
+
+/** @implements {ModuleMetricsProxy} */
+export class ModuleMetricsProxyImpl {
/**
- * NuxNtpBackgroundInteractions enum.
- * These values are persisted to logs and should not be renumbered or
- * re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
+ * @param {string} histogramName The histogram that will record the module
+ * navigation metrics.
*/
- const NuxNtpBackgroundInteractions = {
- PageShown: 0,
- DidNothingAndNavigatedAway: 1,
- DidNothingAndChoseSkip: 2,
- DidNothingAndChoseNext: 3,
- ChoseAnOptionAndNavigatedAway: 4,
- ChoseAnOptionAndChoseSkip: 5,
- ChoseAnOptionAndChoseNext: 6,
- NavigatedAwayThroughBrowserHistory: 7,
- BackgroundImageFailedToLoad: 8,
- BackgroundImageNeverLoaded: 9,
- };
-
- /**
- * NuxGoogleAppsInteractions enum.
- * These values are persisted to logs and should not be renumbered or
- * re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
- */
- const NuxGoogleAppsInteractions = {
- PageShown: 0,
- NotUsed_DEPRECATED: 1,
- GetStarted_DEPRECATED: 2,
- DidNothingAndNavigatedAway: 3,
- DidNothingAndChoseSkip: 4,
- ChoseAnOptionAndNavigatedAway: 5,
- ChoseAnOptionAndChoseSkip: 6,
- ChoseAnOptionAndChoseNext: 7,
- ClickedDisabledNextButtonAndNavigatedAway: 8,
- ClickedDisabledNextButtonAndChoseSkip: 9,
- ClickedDisabledNextButtonAndChoseNext: 10,
- DidNothingAndChoseNext: 11,
- NavigatedAwayThroughBrowserHistory: 12,
- };
-
- /** @interface */
- class ModuleMetricsProxy {
- recordPageShown() {}
-
- recordDidNothingAndNavigatedAway() {}
-
- recordDidNothingAndChoseSkip() {}
-
- recordDidNothingAndChoseNext() {}
-
- recordChoseAnOptionAndNavigatedAway() {}
-
- recordChoseAnOptionAndChoseSkip() {}
-
- recordChoseAnOptionAndChoseNext() {}
-
- recordClickedDisabledNextButtonAndNavigatedAway() {}
-
- recordClickedDisabledNextButtonAndChoseSkip() {}
-
- recordClickedDisabledNextButtonAndChoseNext() {}
-
- recordNavigatedAwayThroughBrowserHistory() {}
+ constructor(histogramName, interactions) {
+ /** @private {string} */
+ this.interactionMetric_ = histogramName;
+ this.interactions_ = interactions;
}
- /** @implements {welcome.ModuleMetricsProxy} */
- class ModuleMetricsProxyImpl {
- /**
- * @param {string} histogramName The histogram that will record the module
- * navigation metrics.
- */
- constructor(histogramName, interactions) {
- /** @private {string} */
- this.interactionMetric_ = histogramName;
- this.interactions_ = interactions;
- }
-
- /** @override */
- recordPageShown() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_, this.interactions_.PageShown,
- Object.keys(this.interactions_).length);
- }
-
- /** @override */
- recordDidNothingAndNavigatedAway() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.DidNothingAndNavigatedAway,
- Object.keys(this.interactions_).length);
- }
-
- /** @override */
- recordDidNothingAndChoseSkip() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_, this.interactions_.DidNothingAndChoseSkip,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordPageShown() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.PageShown,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordDidNothingAndChoseNext() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_, this.interactions_.DidNothingAndChoseNext,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordDidNothingAndNavigatedAway() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.DidNothingAndNavigatedAway,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordChoseAnOptionAndNavigatedAway() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.ChoseAnOptionAndNavigatedAway,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordDidNothingAndChoseSkip() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.DidNothingAndChoseSkip,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordChoseAnOptionAndChoseSkip() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_, this.interactions_.ChoseAnOptionAndChoseSkip,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordDidNothingAndChoseNext() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.DidNothingAndChoseNext,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordChoseAnOptionAndChoseNext() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_, this.interactions_.ChoseAnOptionAndChoseNext,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordChoseAnOptionAndNavigatedAway() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_,
+ this.interactions_.ChoseAnOptionAndNavigatedAway,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordClickedDisabledNextButtonAndNavigatedAway() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.ClickedDisabledNextButtonAndNavigatedAway,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordChoseAnOptionAndChoseSkip() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.ChoseAnOptionAndChoseSkip,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordClickedDisabledNextButtonAndChoseSkip() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.ClickedDisabledNextButtonAndChoseSkip,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordChoseAnOptionAndChoseNext() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_, this.interactions_.ChoseAnOptionAndChoseNext,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordClickedDisabledNextButtonAndChoseNext() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.ClickedDisabledNextButtonAndChoseNext,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordClickedDisabledNextButtonAndNavigatedAway() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_,
+ this.interactions_.ClickedDisabledNextButtonAndNavigatedAway,
+ Object.keys(this.interactions_).length);
+ }
- /** @override */
- recordNavigatedAwayThroughBrowserHistory() {
- chrome.metricsPrivate.recordEnumerationValue(
- this.interactionMetric_,
- this.interactions_.NavigatedAwayThroughBrowserHistory,
- Object.keys(this.interactions_).length);
- }
+ /** @override */
+ recordClickedDisabledNextButtonAndChoseSkip() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_,
+ this.interactions_.ClickedDisabledNextButtonAndChoseSkip,
+ Object.keys(this.interactions_).length);
}
- class ModuleMetricsManager {
- /** @param {welcome.ModuleMetricsProxy} metricsProxy */
- constructor(metricsProxy) {
- this.metricsProxy_ = metricsProxy;
-
- this.options_ = {
- didNothing: {
- andNavigatedAway: metricsProxy.recordDidNothingAndNavigatedAway,
- andChoseSkip: metricsProxy.recordDidNothingAndChoseSkip,
- andChoseNext: metricsProxy.recordDidNothingAndChoseNext,
- },
- choseAnOption: {
- andNavigatedAway: metricsProxy.recordChoseAnOptionAndNavigatedAway,
- andChoseSkip: metricsProxy.recordChoseAnOptionAndChoseSkip,
- andChoseNext: metricsProxy.recordChoseAnOptionAndChoseNext,
- },
- clickedDisabledNextButton: {
- andNavigatedAway:
- metricsProxy.recordClickedDisabledNextButtonAndNavigatedAway,
- andChoseSkip:
- metricsProxy.recordClickedDisabledNextButtonAndChoseSkip,
- andChoseNext:
- metricsProxy.recordClickedDisabledNextButtonAndChoseNext,
- },
- };
-
- this.firstPart = this.options_.didNothing;
- }
+ /** @override */
+ recordClickedDisabledNextButtonAndChoseNext() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_,
+ this.interactions_.ClickedDisabledNextButtonAndChoseNext,
+ Object.keys(this.interactions_).length);
+ }
- recordPageInitialized() {
- this.metricsProxy_.recordPageShown();
- this.firstPart = this.options_.didNothing;
- }
+ /** @override */
+ recordNavigatedAwayThroughBrowserHistory() {
+ chrome.metricsPrivate.recordEnumerationValue(
+ this.interactionMetric_,
+ this.interactions_.NavigatedAwayThroughBrowserHistory,
+ Object.keys(this.interactions_).length);
+ }
+}
+
+export class ModuleMetricsManager {
+ /** @param {ModuleMetricsProxy} metricsProxy */
+ constructor(metricsProxy) {
+ this.metricsProxy_ = metricsProxy;
+
+ this.options_ = {
+ didNothing: {
+ andNavigatedAway: metricsProxy.recordDidNothingAndNavigatedAway,
+ andChoseSkip: metricsProxy.recordDidNothingAndChoseSkip,
+ andChoseNext: metricsProxy.recordDidNothingAndChoseNext,
+ },
+ choseAnOption: {
+ andNavigatedAway: metricsProxy.recordChoseAnOptionAndNavigatedAway,
+ andChoseSkip: metricsProxy.recordChoseAnOptionAndChoseSkip,
+ andChoseNext: metricsProxy.recordChoseAnOptionAndChoseNext,
+ },
+ clickedDisabledNextButton: {
+ andNavigatedAway:
+ metricsProxy.recordClickedDisabledNextButtonAndNavigatedAway,
+ andChoseSkip: metricsProxy.recordClickedDisabledNextButtonAndChoseSkip,
+ andChoseNext: metricsProxy.recordClickedDisabledNextButtonAndChoseNext,
+ },
+ };
+
+ this.firstPart = this.options_.didNothing;
+ }
- recordClickedOption() {
- // Only overwrite this.firstPart if it's not overwritten already
- if (this.firstPart == this.options_.didNothing) {
- this.firstPart = this.options_.choseAnOption;
- }
- }
+ recordPageInitialized() {
+ this.metricsProxy_.recordPageShown();
+ this.firstPart = this.options_.didNothing;
+ }
- recordClickedDisabledButton() {
- // Only overwrite this.firstPart if it's not overwritten already
- if (this.firstPart == this.options_.didNothing) {
- this.firstPart = this.options_.clickedDisabledNextButton;
- }
+ recordClickedOption() {
+ // Only overwrite this.firstPart if it's not overwritten already
+ if (this.firstPart == this.options_.didNothing) {
+ this.firstPart = this.options_.choseAnOption;
}
+ }
- recordNoThanks() {
- this.firstPart.andChoseSkip.call(this.metricsProxy_);
+ recordClickedDisabledButton() {
+ // Only overwrite this.firstPart if it's not overwritten already
+ if (this.firstPart == this.options_.didNothing) {
+ this.firstPart = this.options_.clickedDisabledNextButton;
}
+ }
- recordGetStarted() {
- this.firstPart.andChoseNext.call(this.metricsProxy_);
- }
+ recordNoThanks() {
+ this.firstPart.andChoseSkip.call(this.metricsProxy_);
+ }
- recordNavigatedAway() {
- this.firstPart.andNavigatedAway.call(this.metricsProxy_);
- }
+ recordGetStarted() {
+ this.firstPart.andChoseNext.call(this.metricsProxy_);
+ }
- recordBrowserBackOrForward() {
- this.metricsProxy_.recordNavigatedAwayThroughBrowserHistory();
- }
+ recordNavigatedAway() {
+ this.firstPart.andNavigatedAway.call(this.metricsProxy_);
}
- return {
- ModuleMetricsManager: ModuleMetricsManager,
- ModuleMetricsProxyImpl: ModuleMetricsProxyImpl,
- ModuleMetricsProxy: ModuleMetricsProxy,
- NuxGoogleAppsInteractions: NuxGoogleAppsInteractions,
- NuxNtpBackgroundInteractions: NuxNtpBackgroundInteractions,
- };
-});
+ recordBrowserBackOrForward() {
+ this.metricsProxy_.recordNavigatedAwayThroughBrowserHistory();
+ }
+}
diff --git a/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html
index 99846f3120f..403ee035ba4 100644
--- a/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html
+++ b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.html
@@ -1,51 +1,44 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<template>
+ <style>
+ :host {
+ --navi-border-color: var(--google-grey-refresh-300);
+ --navi-check-icon-color: lightgrey;
+ --navi-keyboard-focus-color: rgba(var(--google-blue-600-rgb), .4);
+ --navi-option-box-shadow:
+ 0 1px 2px 0 rgba(var(--google-grey-800-rgb), .3),
+ 0 3px 6px 2px rgba(var(--google-grey-800-rgb), .15);
+ --navi-option-icon-shadow-color: var(--google-grey-refresh-100);
+ --navi-shape-blue-color: rgb(26, 115, 232); /* #1A73E8 */
+ --navi-shape-green-color: rgb(49, 167, 83); /* #31A753 */
+ --navi-shape-grey-color: rgb(241, 243, 244); /* #F1F3F4 */
+ --navi-shape-red-color: rgb(233, 66, 53); /* #E94235 */
+ --navi-shape-yellow-dots-color: rgb(253, 214, 99); /* #FDD663 */
+ --navi-shape-yellow-semicircle-color: rgb(250, 207, 76); /* #FACF4C */
+ --navi-step-indicator-active-color:
+ rgba(var(--google-blue-600-rgb), .5);
+ --navi-step-indicator-color: var(--google-grey-200);
+ --navi-wallpaper-text-color: var(--google-grey-refresh-700);
+ }
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
-
-<dom-module id="navi-colors-css">
- <template>
- <style>
+ @media (prefers-color-scheme: dark) {
:host {
- --navi-border-color: var(--google-grey-refresh-300);
- --navi-check-icon-color: lightgrey;
- --navi-keyboard-focus-color: rgba(var(--google-blue-600-rgb), .4);
- --navi-option-box-shadow:
- 0 1px 2px 0 rgba(var(--google-grey-800-rgb), .3),
- 0 3px 6px 2px rgba(var(--google-grey-800-rgb), .15);
- --navi-option-icon-shadow-color: var(--google-grey-refresh-100);
- --navi-shape-blue-color: rgb(26, 115, 232); /* #1A73E8 */
- --navi-shape-green-color: rgb(49, 167, 83); /* #31A753 */
- --navi-shape-grey-color: rgb(241, 243, 244); /* #F1F3F4 */
- --navi-shape-red-color: rgb(233, 66, 53); /* #E94235 */
- --navi-shape-yellow-dots-color: rgb(253, 214, 99); /* #FDD663 */
- --navi-shape-yellow-semicircle-color: rgb(250, 207, 76); /* #FACF4C */
- --navi-step-indicator-active-color:
- rgba(var(--google-blue-600-rgb), .5);
- --navi-step-indicator-color: var(--google-grey-200);
- --navi-wallpaper-text-color: var(--google-grey-refresh-700);
- }
-
- @media (prefers-color-scheme: dark) {
- :host {
- --navi-border-color: var(--google-grey-refresh-700);
- --navi-check-icon-color: var(--google-grey-refresh-700);
- --navi-keyboard-focus-color:
- rgba(var(--google-blue-refresh-300-rgb), .5);
- --navi-option-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .3),
- 0 3px 6px 2px rgba(0, 0, 0, .15);
- --navi-option-icon-shadow-color: var(--google-grey-refresh-700);
- --navi-shape-blue-color: rgb(138, 180, 248); /* #8AB4F8 */
- --navi-shape-green-color: rgb(129, 201, 149); /* #81C995 */
- --navi-shape-grey-color: rgb(154, 160, 166); /* #9AA0A6 */
- --navi-shape-red-color: rgb(238, 103, 92); /* #EE675C */
- /* --navi-shape-yellow-dots-color is same color in dark mode */
- --navi-shape-yellow-semicircle-color: rgb(253, 214, 99); /* #FDD663 */
- --navi-step-indicator-active-color: var(--google-blue-refresh-300);
- --navi-step-indicator-color: var(--google-grey-refresh-500);
- --navi-wallpaper-text-color: var(--google-grey-200);
- }
+ --navi-border-color: var(--google-grey-refresh-700);
+ --navi-check-icon-color: var(--google-grey-refresh-700);
+ --navi-keyboard-focus-color:
+ rgba(var(--google-blue-refresh-300-rgb), .5);
+ --navi-option-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .3),
+ 0 3px 6px 2px rgba(0, 0, 0, .15);
+ --navi-option-icon-shadow-color: var(--google-grey-refresh-700);
+ --navi-shape-blue-color: rgb(138, 180, 248); /* #8AB4F8 */
+ --navi-shape-green-color: rgb(129, 201, 149); /* #81C995 */
+ --navi-shape-grey-color: rgb(154, 160, 166); /* #9AA0A6 */
+ --navi-shape-red-color: rgb(238, 103, 92); /* #EE675C */
+ /* --navi-shape-yellow-dots-color is same color in dark mode */
+ --navi-shape-yellow-semicircle-color: rgb(253, 214, 99); /* #FDD663 */
+ --navi-step-indicator-active-color: var(--google-blue-refresh-300);
+ --navi-step-indicator-color: var(--google-grey-refresh-500);
+ --navi-wallpaper-text-color: var(--google-grey-200);
}
- </style>
- </template>
-</dom-module>
+ }
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.js b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.js
new file mode 100644
index 00000000000..f803f2d1757
--- /dev/null
+++ b/chromium/chrome/browser/resources/welcome/shared/navi_colors_css.js
@@ -0,0 +1,12 @@
+// 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 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import 'chrome://resources/cr_elements/md_select_css.m.js';
+
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('navi-colors-css');
diff --git a/chromium/chrome/browser/resources/welcome/shared/nux_types.js b/chromium/chrome/browser/resources/welcome/shared/nux_types.js
index d8fd86dfc57..3c8be494718 100644
--- a/chromium/chrome/browser/resources/welcome/shared/nux_types.js
+++ b/chromium/chrome/browser/resources/welcome/shared/nux_types.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.exportPath('welcome');
-
/**
* @typedef {{
* id: number,
@@ -12,7 +10,7 @@ cr.exportPath('welcome');
* url: string,
* }}
*/
-welcome.BookmarkListItem;
+export let BookmarkListItem;
/**
* @typedef {{
@@ -20,7 +18,7 @@ welcome.BookmarkListItem;
* active: number,
* }}
*/
-welcome.stepIndicatorModel;
+export let stepIndicatorModel;
/**
* TODO(hcarmona): somehow reuse from
@@ -32,4 +30,4 @@ welcome.stepIndicatorModel;
* isUnknownError: boolean,
* }};
*/
-welcome.DefaultBrowserInfo;
+export let DefaultBrowserInfo;
diff --git a/chromium/chrome/browser/resources/welcome/shared/onboarding_background.html b/chromium/chrome/browser/resources/welcome/shared/onboarding_background.html
index 643c8eff8ee..e51c6d933b4 100644
--- a/chromium/chrome/browser/resources/welcome/shared/onboarding_background.html
+++ b/chromium/chrome/browser/resources/welcome/shared/onboarding_background.html
@@ -1,187 +1,180 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<dom-module id="onboarding-background">
- <template>
- <style>
- @keyframes blue-circle-anim-x {
- 50% {
- animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transform: translateX(44px);
- }
- }
-
- @keyframes blue-circle-anim-y {
- 50% {
- animation-timing-function: cubic-bezier(0.55, 0, 0.2, 1);
- transform: translateY(17px);
- }
- }
-
- @keyframes green-rectangle-anim {
- 100% {
- transform: rotate(360deg);
- }
- }
-
- @keyframes red-triangle-anim {
- 50% {
- animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transform: translateY(25px) rotate(-53deg);
- }
- }
-
- @keyframes yellow-semicircle-anim {
- 40% {
- animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transform: translateY(40px) rotate(-1deg);
- }
- }
-
- @keyframes grey-rounded-rectangle-anim {
- 65% {
- animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transform: translateY(-48px) rotate(-75deg);
- }
- }
-
- :host {
- bottom: 0;
- left: 0;
- margin: auto;
- overflow: hidden;
- position: absolute;
- right: 0;
- top: 0;
- z-index: -1;
- }
-
- /* The container is necessary in order for :host to hide overflowing SVGs
- correctly without disturbing their positions. */
- #container {
- height: 100%;
- left: 50%;
- min-height: 700px;
- min-width: 1024px;
- position: absolute;
- top: 50%;
- transform: translate(-50%, -50%);
- width: 100%;
- }
-
- img,
- span {
- position: absolute;
- }
-
- #blue-circle-container {
- animation: blue-circle-anim-x 9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
- left: calc(13% - 50px); /* Relative to #yellow-dots. */
- top: calc(18% - 26px); /* Relative to #yellow-dots. */
- }
-
- #blue-circle-container::after {
- -webkit-mask: url(../images/background_svgs/blue_circle.svg) no-repeat
- top left;
- animation: blue-circle-anim-y 9s cubic-bezier(0.25, 0, 0.2, 1) infinite;
- background-color: var(--navi-shape-blue-color);
- content: ' '; /* Content needs to be non-empty */
- height: 43px;
- position: absolute;
- width: 43px;
- }
-
- #yellow-dots {
- -webkit-mask: url(../images/background_svgs/yellow_dots.svg) no-repeat
- top left;
- background-color: var(--navi-shape-yellow-dots-color);
- content: ' '; /* Content needs to be non-empty */
- height: 57px;
- left: 13%;
- top: 18%;
- width: 76px;
- }
-
- #grey-rounded-rectangle {
- -webkit-mask: url(../images/background_svgs/grey_rounded_rectangle.svg)
- no-repeat top left;
- animation: grey-rounded-rectangle-anim 10s cubic-bezier(0.4, 0, 0.2, 1)
- infinite;
- background-color: var(--navi-shape-grey-color);
- content: ' '; /* Content needs to be non-empty */
- height: 132px;
- left: -42px;
- top: 45%;
- width: 132px;
- }
-
- #red-triangle {
- -webkit-mask: url(../images/background_svgs/red_triangle.svg) no-repeat
- bottom left;
- animation: red-triangle-anim 9.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
- background-color: var(--navi-shape-red-color);
- bottom: 15%;
- content: ' '; /* Content needs to be non-empty */
- height: 74px;
- left: 12%;
- width: 65px;
- }
-
- #yellow-semicircle {
- -webkit-mask: url(../images/background_svgs/yellow_semicircle.svg)
- no-repeat top right;
- animation: yellow-semicircle-anim 10s cubic-bezier(0.4, 0, 0.2, 1)
- infinite;
- background-color: var(--navi-shape-yellow-semicircle-color);
- content: ' '; /* Content needs to be non-empty */
- height: 171px;
- right: 28.5%;
- top: -50px;
- transform: rotate(-7deg);
- width: 211px;
- }
-
- #green-rectangle {
- -webkit-mask: url(../images/background_svgs/green_rectangle.svg)
- no-repeat bottom right;
- animation: green-rectangle-anim 40s infinite linear;
- background-color: var(--navi-shape-green-color);
- bottom: 8%;
- content: ' '; /* Content needs to be non-empty */
- height: 371px;
- right: -255px;
- width: 371px;
- }
-
- #grey-oval {
- -webkit-mask: url(../images/background_svgs/grey_oval.svg) no-repeat
- bottom right;
- background-color: var(--navi-shape-grey-color);
- bottom: calc(8% + 24px); /* Relative to green-rectangle. */
- content: ' '; /* Content needs to be non-empty */
- height: 100px;
- mix-blend-mode: multiply;
- right: 48px;
- width: 100px;
- }
-
- @media (prefers-color-scheme: dark) {
- #grey-oval {
- mix-blend-mode: screen;
- }
- }
- </style>
- <div id="container">
- <!-- Using span as container for an :after element that actually contains
- the blue-circle svg, because the animation needs to curve so x and y
- needs to be animated separately. -->
- <span id="blue-circle-container"></span>
- <span id="green-rectangle"></span>
- <span id="grey-oval"></span>
- <span id="grey-rounded-rectangle"></span>
- <span id="red-triangle"></span>
- <span id="yellow-dots"></span>
- <span id="yellow-semicircle"></span>
- </div>
- </template>
- <script src="onboarding_background.js"></script>
-</dom-module>
+<style>
+ @keyframes blue-circle-anim-x {
+ 50% {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateX(44px);
+ }
+ }
+
+ @keyframes blue-circle-anim-y {
+ 50% {
+ animation-timing-function: cubic-bezier(0.55, 0, 0.2, 1);
+ transform: translateY(17px);
+ }
+ }
+
+ @keyframes green-rectangle-anim {
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes red-triangle-anim {
+ 50% {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateY(25px) rotate(-53deg);
+ }
+ }
+
+ @keyframes yellow-semicircle-anim {
+ 40% {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateY(40px) rotate(-1deg);
+ }
+ }
+
+ @keyframes grey-rounded-rectangle-anim {
+ 65% {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateY(-48px) rotate(-75deg);
+ }
+ }
+
+ :host {
+ bottom: 0;
+ left: 0;
+ margin: auto;
+ overflow: hidden;
+ position: absolute;
+ right: 0;
+ top: 0;
+ z-index: -1;
+ }
+
+ /* The container is necessary in order for :host to hide overflowing SVGs
+ correctly without disturbing their positions. */
+ #container {
+ height: 100%;
+ left: 50%;
+ min-height: 700px;
+ min-width: 1024px;
+ position: absolute;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+ }
+
+ img,
+ span {
+ position: absolute;
+ }
+
+ #blue-circle-container {
+ animation: blue-circle-anim-x 9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
+ left: calc(13% - 50px); /* Relative to #yellow-dots. */
+ top: calc(18% - 26px); /* Relative to #yellow-dots. */
+ }
+
+ #blue-circle-container::after {
+ -webkit-mask: url(../images/background_svgs/blue_circle.svg) no-repeat
+ top left;
+ animation: blue-circle-anim-y 9s cubic-bezier(0.25, 0, 0.2, 1) infinite;
+ background-color: var(--navi-shape-blue-color);
+ content: ' '; /* Content needs to be non-empty */
+ height: 43px;
+ position: absolute;
+ width: 43px;
+ }
+
+ #yellow-dots {
+ -webkit-mask: url(../images/background_svgs/yellow_dots.svg) no-repeat
+ top left;
+ background-color: var(--navi-shape-yellow-dots-color);
+ content: ' '; /* Content needs to be non-empty */
+ height: 57px;
+ left: 13%;
+ top: 18%;
+ width: 76px;
+ }
+
+ #grey-rounded-rectangle {
+ -webkit-mask: url(../images/background_svgs/grey_rounded_rectangle.svg)
+ no-repeat top left;
+ animation: grey-rounded-rectangle-anim 10s cubic-bezier(0.4, 0, 0.2, 1)
+ infinite;
+ background-color: var(--navi-shape-grey-color);
+ content: ' '; /* Content needs to be non-empty */
+ height: 132px;
+ left: -42px;
+ top: 45%;
+ width: 132px;
+ }
+
+ #red-triangle {
+ -webkit-mask: url(../images/background_svgs/red_triangle.svg) no-repeat
+ bottom left;
+ animation: red-triangle-anim 9.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
+ background-color: var(--navi-shape-red-color);
+ bottom: 15%;
+ content: ' '; /* Content needs to be non-empty */
+ height: 74px;
+ left: 12%;
+ width: 65px;
+ }
+
+ #yellow-semicircle {
+ -webkit-mask: url(../images/background_svgs/yellow_semicircle.svg)
+ no-repeat top right;
+ animation: yellow-semicircle-anim 10s cubic-bezier(0.4, 0, 0.2, 1)
+ infinite;
+ background-color: var(--navi-shape-yellow-semicircle-color);
+ content: ' '; /* Content needs to be non-empty */
+ height: 171px;
+ right: 28.5%;
+ top: -50px;
+ transform: rotate(-7deg);
+ width: 211px;
+ }
+
+ #green-rectangle {
+ -webkit-mask: url(../images/background_svgs/green_rectangle.svg)
+ no-repeat bottom right;
+ animation: green-rectangle-anim 40s infinite linear;
+ background-color: var(--navi-shape-green-color);
+ bottom: 8%;
+ content: ' '; /* Content needs to be non-empty */
+ height: 371px;
+ right: -255px;
+ width: 371px;
+ }
+
+ #grey-oval {
+ -webkit-mask: url(../images/background_svgs/grey_oval.svg) no-repeat
+ bottom right;
+ background-color: var(--navi-shape-grey-color);
+ bottom: calc(8% + 24px); /* Relative to green-rectangle. */
+ content: ' '; /* Content needs to be non-empty */
+ height: 100px;
+ mix-blend-mode: multiply;
+ right: 48px;
+ width: 100px;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ #grey-oval {
+ mix-blend-mode: screen;
+ }
+ }
+</style>
+<div id="container">
+ <!-- Using span as container for an :after element that actually contains
+ the blue-circle svg, because the animation needs to curve so x and y
+ needs to be animated separately. -->
+ <span id="blue-circle-container"></span>
+ <span id="green-rectangle"></span>
+ <span id="grey-oval"></span>
+ <span id="grey-rounded-rectangle"></span>
+ <span id="red-triangle"></span>
+ <span id="yellow-dots"></span>
+ <span id="yellow-semicircle"></span>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/shared/onboarding_background.js b/chromium/chrome/browser/resources/welcome/shared/onboarding_background.js
index 12358fa84c5..98f2999cd60 100644
--- a/chromium/chrome/browser/resources/welcome/shared/onboarding_background.js
+++ b/chromium/chrome/browser/resources/welcome/shared/onboarding_background.js
@@ -6,6 +6,11 @@
* @fileoverview This element contains a set of SVGs that together acts as an
* animated and responsive background for any page that contains it.
*/
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
Polymer({
is: 'onboarding-background',
-}); \ No newline at end of file
+
+ _template: html`{__html_template__}`,
+});
diff --git a/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.html b/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.html
index 3d662b4dac4..8d2c1b78f0d 100644
--- a/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.html
+++ b/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.html
@@ -1,55 +1,48 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<template>
+ <style include="navi-colors-css">
+ #container {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin: auto;
+ min-height: 100%;
+ min-width: 800px;
+ position: relative;
+ }
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="navi_colors_css.html">
+ h1 {
+ color: var(--cr-primary-text-color);
+ font-size: 4rem;
+ margin-bottom: 40px;
+ margin-top: 16px;
+ text-align: center;
+ }
-<dom-module id="splash-pages-shared-css">
- <template>
- <style include="navi-colors-css">
- #container {
- align-items: center;
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin: auto;
- min-height: 100%;
- min-width: 800px;
- position: relative;
- }
+ h2 {
+ color: var(--cr-secondary-text-color);
+ font-size: 1.5rem;
+ font-weight: 500;
+ line-height: 2.25rem;
+ margin: 0;
+ opacity: 0.8;
+ text-align: center;
+ }
- h1 {
- color: var(--cr-primary-text-color);
- font-size: 4rem;
- margin-bottom: 40px;
- margin-top: 16px;
- text-align: center;
- }
+ cr-button {
+ font-size: 1rem;
+ height: 3rem;
+ padding-bottom: 12px;
+ padding-top: 12px;
+ text-align: center;
+ white-space: nowrap;
+ width: 256px;
+ }
- h2 {
- color: var(--cr-secondary-text-color);
- font-size: 1.5rem;
- font-weight: 500;
- line-height: 2.25rem;
- margin: 0;
- opacity: 0.8;
- text-align: center;
- }
-
- cr-button {
- font-size: 1rem;
- height: 3rem;
- padding-bottom: 12px;
- padding-top: 12px;
- text-align: center;
- white-space: nowrap;
- width: 256px;
- }
-
- .action-link {
- font-size: 1rem;
- font-weight: 500;
- margin-top: 24px;
- }
- </style>
- </template>
-</dom-module>
+ .action-link {
+ font-size: 1rem;
+ font-weight: 500;
+ margin-top: 24px;
+ }
+ </style>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.js b/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.js
new file mode 100644
index 00000000000..896d7adc612
--- /dev/null
+++ b/chromium/chrome/browser/resources/welcome/shared/splash_pages_shared_css.js
@@ -0,0 +1,12 @@
+// 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 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import './navi_colors_css.js';
+
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styleElement = document.createElement('dom-module');
+styleElement.innerHTML = `{__html_template__}`;
+styleElement.register('splash-pages-shared-css');
diff --git a/chromium/chrome/browser/resources/welcome/shared/step_indicator.html b/chromium/chrome/browser/resources/welcome/shared/step_indicator.html
index 4123eb53301..4caec81cbe7 100644
--- a/chromium/chrome/browser/resources/welcome/shared/step_indicator.html
+++ b/chromium/chrome/browser/resources/welcome/shared/step_indicator.html
@@ -1,32 +1,22 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="navi-colors-css">
+ :host {
+ align-items: center;
+ display: flex;
+ }
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="navi_colors_css.html">
+ span {
+ background: var(--navi-step-indicator-color);
+ border-radius: 50%;
+ display: inline-block;
+ height: 8px;
+ margin: 0 4px;
+ width: 8px;
+ }
-<dom-module id="step-indicator">
- <template>
- <style include="navi-colors-css">
- :host {
- align-items: center;
- display: flex;
- }
-
- span {
- background: var(--navi-step-indicator-color);
- border-radius: 50%;
- display: inline-block;
- height: 8px;
- margin: 0 4px;
- width: 8px;
- }
-
- span.active {
- background: var(--navi-step-indicator-active-color);
- }
- </style>
- <template is="dom-repeat" items="[[dots_]]">
- <span class$="[[getActiveClass_(index, model.active)]]"></span>
- </template>
- </template>
- <script src="step_indicator.js"></script>
-</dom-module>
+ span.active {
+ background: var(--navi-step-indicator-active-color);
+ }
+</style>
+<template is="dom-repeat" items="[[dots_]]">
+ <span class$="[[getActiveClass_(index, model.active)]]"></span>
+</template>
diff --git a/chromium/chrome/browser/resources/welcome/shared/step_indicator.js b/chromium/chrome/browser/resources/welcome/shared/step_indicator.js
index 4af45dc89f1..8d4b45c0ff5 100644
--- a/chromium/chrome/browser/resources/welcome/shared/step_indicator.js
+++ b/chromium/chrome/browser/resources/welcome/shared/step_indicator.js
@@ -6,11 +6,20 @@
* @fileoverview This element contains a set of SVGs that together acts as an
* animated and responsive background for any page that contains it.
*/
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import './navi_colors_css.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {stepIndicatorModel} from './nux_types.js';
+
Polymer({
is: 'step-indicator',
+ _template: html`{__html_template__}`,
+
properties: {
- /** @type {welcome.stepIndicatorModel} */
+ /** @type {stepIndicatorModel} */
model: Object,
/** @private */
diff --git a/chromium/chrome/browser/resources/welcome/signin_view.html b/chromium/chrome/browser/resources/welcome/signin_view.html
index d5fc11e623e..61fa2673b8c 100644
--- a/chromium/chrome/browser/resources/welcome/signin_view.html
+++ b/chromium/chrome/browser/resources/welcome/signin_view.html
@@ -1,38 +1,20 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="animations action-link-style splash-pages-shared-css">
+ onboarding-background {
+ --animation-delay: 150ms;
+ }
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
-<link rel="import" href="navigation_behavior.html">
-<link rel="import" href="shared/action_link_style_css.html">
-<link rel="import" href="shared/animations_css.html">
-<link rel="import" href="shared/i18n_setup.html">
-<link rel="import" href="shared/onboarding_background.html">
-<link rel="import" href="shared/splash_pages_shared_css.html">
-<link rel="import" href="signin_view_proxy.html">
-<link rel="import" href="welcome_browser_proxy.html">
-
-<dom-module id="signin-view">
- <template>
- <style include="animations action-link-style splash-pages-shared-css">
- onboarding-background {
- --animation-delay: 150ms;
- }
-
- h1 {
- outline: none;
- }
- </style>
- <div id="container">
- <onboarding-background class="fade-in"></onboarding-background>
- <h2>$i18n{signInSubHeader}</h2>
- <h1 tabindex="-1">$i18n{signInHeader}</h1>
- <cr-button class="action-button" on-click="onSignInClick_">
- $i18n{signIn}
- </cr-button>
- <button class="action-link" on-click="onNoThanksClick_">
- $i18n{noThanks}
- </button>
- </div>
- </template>
- <script src="signin_view.js"></script>
-</dom-module>
+ h1 {
+ outline: none;
+ }
+</style>
+<div id="container">
+ <onboarding-background class="fade-in"></onboarding-background>
+ <h2>$i18n{signInSubHeader}</h2>
+ <h1 tabindex="-1">$i18n{signInHeader}</h1>
+ <cr-button class="action-button" on-click="onSignInClick_">
+ $i18n{signIn}
+ </cr-button>
+ <button class="action-link" on-click="onNoThanksClick_">
+ $i18n{noThanks}
+ </button>
+</div>
diff --git a/chromium/chrome/browser/resources/welcome/signin_view.js b/chromium/chrome/browser/resources/welcome/signin_view.js
index 15096824fc1..b0c8befc300 100644
--- a/chromium/chrome/browser/resources/welcome/signin_view.js
+++ b/chromium/chrome/browser/resources/welcome/signin_view.js
@@ -2,24 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
+import './shared/action_link_style_css.js';
+import './shared/animations_css.js';
+import './shared/onboarding_background.js';
+import './shared/splash_pages_shared_css.js';
+import '../strings.m.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from './navigation_behavior.js';
+import {SigninViewProxy, SigninViewProxyImpl} from './signin_view_proxy.js';
+import {WelcomeBrowserProxy, WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
+
Polymer({
is: 'signin-view',
- behaviors: [welcome.NavigationBehavior],
+ _template: html`{__html_template__}`,
+
+ behaviors: [NavigationBehavior],
/** @private {boolean} */
finalized_: false,
- /** @private {?welcome.WelcomeBrowserProxy} */
+ /** @private {?WelcomeBrowserProxy} */
welcomeBrowserProxy_: null,
- /** @private {?welcome.SigninViewProxy} */
+ /** @private {?SigninViewProxy} */
signinViewProxy_: null,
/** @override */
ready: function() {
- this.welcomeBrowserProxy_ = welcome.WelcomeBrowserProxyImpl.getInstance();
- this.signinViewProxy_ = welcome.SigninViewProxyImpl.getInstance();
+ this.welcomeBrowserProxy_ = WelcomeBrowserProxyImpl.getInstance();
+ this.signinViewProxy_ = SigninViewProxyImpl.getInstance();
},
onRouteEnter: function() {
diff --git a/chromium/chrome/browser/resources/welcome/signin_view_proxy.html b/chromium/chrome/browser/resources/welcome/signin_view_proxy.html
deleted file mode 100644
index 5d26af4e3f0..00000000000
--- a/chromium/chrome/browser/resources/welcome/signin_view_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="signin_view_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/signin_view_proxy.js b/chromium/chrome/browser/resources/welcome/signin_view_proxy.js
index 0e731b9df18..43266ea4036 100644
--- a/chromium/chrome/browser/resources/welcome/signin_view_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/signin_view_proxy.js
@@ -2,79 +2,74 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-cr.define('welcome', function() {
- const NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME =
- 'FirstRun.NewUserExperience.SignInInterstitialInteraction';
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
- /**
- * NuxSignInInterstitialInteractions enum.
- * These values are persisted to logs and should not be renumbered or re-used.
- * See tools/metrics/histograms/enums.xml.
- * @enum {number}
- */
- const NuxSignInInterstitialInteractions = {
- PageShown: 0,
- NavigatedAway: 1,
- Skip: 2,
- SignIn: 3,
- NavigatedAwayThroughBrowserHistory: 4,
- };
+const NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME =
+ 'FirstRun.NewUserExperience.SignInInterstitialInteraction';
- const NUX_SIGNIN_VIEW_INTERACTIONS_COUNT =
- Object.keys(NuxSignInInterstitialInteractions).length;
+/**
+ * NuxSignInInterstitialInteractions enum.
+ * These values are persisted to logs and should not be renumbered or re-used.
+ * See tools/metrics/histograms/enums.xml.
+ * @enum {number}
+ */
+const NuxSignInInterstitialInteractions = {
+ PageShown: 0,
+ NavigatedAway: 1,
+ Skip: 2,
+ SignIn: 3,
+ NavigatedAwayThroughBrowserHistory: 4,
+};
- /** @interface */
- class SigninViewProxy {
- recordPageShown() {}
- recordNavigatedAway() {}
- recordNavigatedAwayThroughBrowserHistory() {}
- recordSkip() {}
- recordSignIn() {}
- }
+const NUX_SIGNIN_VIEW_INTERACTIONS_COUNT =
+ Object.keys(NuxSignInInterstitialInteractions).length;
- /** @implements {welcome.SigninViewProxy} */
- class SigninViewProxyImpl {
- /** @override */
- recordPageShown() {
- this.recordInteraction_(NuxSignInInterstitialInteractions.PageShown);
- }
+/** @interface */
+export class SigninViewProxy {
+ recordPageShown() {}
+ recordNavigatedAway() {}
+ recordNavigatedAwayThroughBrowserHistory() {}
+ recordSkip() {}
+ recordSignIn() {}
+}
- /** @override */
- recordNavigatedAway() {
- this.recordInteraction_(NuxSignInInterstitialInteractions.NavigatedAway);
- }
+/** @implements {SigninViewProxy} */
+export class SigninViewProxyImpl {
+ /** @override */
+ recordPageShown() {
+ this.recordInteraction_(NuxSignInInterstitialInteractions.PageShown);
+ }
- /** @override */
- recordNavigatedAwayThroughBrowserHistory() {
- this.recordInteraction_(
- NuxSignInInterstitialInteractions.NavigatedAwayThroughBrowserHistory);
- }
+ /** @override */
+ recordNavigatedAway() {
+ this.recordInteraction_(NuxSignInInterstitialInteractions.NavigatedAway);
+ }
- /** @override */
- recordSkip() {
- this.recordInteraction_(NuxSignInInterstitialInteractions.Skip);
- }
+ /** @override */
+ recordNavigatedAwayThroughBrowserHistory() {
+ this.recordInteraction_(
+ NuxSignInInterstitialInteractions.NavigatedAwayThroughBrowserHistory);
+ }
- /** @override */
- recordSignIn() {
- this.recordInteraction_(NuxSignInInterstitialInteractions.SignIn);
- }
+ /** @override */
+ recordSkip() {
+ this.recordInteraction_(NuxSignInInterstitialInteractions.Skip);
+ }
- /**
- * @param {number} interaction
- * @private
- */
- recordInteraction_(interaction) {
- chrome.metricsPrivate.recordEnumerationValue(
- NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME, interaction,
- NUX_SIGNIN_VIEW_INTERACTIONS_COUNT);
- }
+ /** @override */
+ recordSignIn() {
+ this.recordInteraction_(NuxSignInInterstitialInteractions.SignIn);
}
- cr.addSingletonGetter(SigninViewProxyImpl);
+ /**
+ * @param {number} interaction
+ * @private
+ */
+ recordInteraction_(interaction) {
+ chrome.metricsPrivate.recordEnumerationValue(
+ NUX_SIGNIN_VIEW_INTERACTION_METRIC_NAME, interaction,
+ NUX_SIGNIN_VIEW_INTERACTIONS_COUNT);
+ }
+}
- return {
- SigninViewProxy: SigninViewProxy,
- SigninViewProxyImpl: SigninViewProxyImpl,
- };
-});
+addSingletonGetter(SigninViewProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/welcome.html b/chromium/chrome/browser/resources/welcome/welcome.html
index e2a37c5b0a1..88145e7cae9 100644
--- a/chromium/chrome/browser/resources/welcome/welcome.html
+++ b/chromium/chrome/browser/resources/welcome/welcome.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title>$i18n{headerText}</title>
- <link rel="import" href="welcome_app.html">
+ <script type="module" src="welcome_app.js"></script>
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
</head>
@@ -16,7 +16,7 @@
}
</style>
<welcome-app></welcome-app>
- <script src="/welcome.js"></script>
+ <script type="module" src="welcome.js"></script>
<link rel="stylesheet" href="chrome://welcome/welcome.css">
</body>
</html>
diff --git a/chromium/chrome/browser/resources/welcome/welcome.js b/chromium/chrome/browser/resources/welcome/welcome.js
index 2e78a6476da..198e3658e74 100644
--- a/chromium/chrome/browser/resources/welcome/welcome.js
+++ b/chromium/chrome/browser/resources/welcome/welcome.js
@@ -7,9 +7,10 @@
* it's included more than once, which can happen when an include is misspelled.
*/
-cr.exportPath('welcome');
+import {assert} from 'chrome://resources/js/assert.m.js';
+
assert(
- !welcome.defaultResourceLoaded,
+ !window.defaultResourceLoaded,
'welcome.js run twice. You probably have an invalid import.');
/** Global defined when the main welcome script runs. */
-welcome.defaultResourceLoaded = true;
+window.defaultResourceLoaded = true;
diff --git a/chromium/chrome/browser/resources/welcome/welcome_app.html b/chromium/chrome/browser/resources/welcome/welcome_app.html
index a520eaaaf11..21e0477f9c7 100644
--- a/chromium/chrome/browser/resources/welcome/welcome_app.html
+++ b/chromium/chrome/browser/resources/welcome/welcome_app.html
@@ -1,50 +1,29 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="cr-hidden-style">
+ #viewManager {
+ display: flex;
+ font-size: 100%;
+ margin: 0;
+ min-height: 100vh;
+ }
-<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.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">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="google_apps/nux_google_apps.html">
-<link rel="import" href="landing_view.html">
-<link rel="import" href="navigation_behavior.html">
-<link rel="import" href="ntp_background/nux_ntp_background.html">
-<link rel="import" href="set_as_default/nux_set_as_default.html">
-<link rel="import" href="set_as_default/nux_set_as_default_proxy.html">
-<link rel="import" href="shared/bookmark_proxy.html">
-<link rel="import" href="shared/i18n_setup.html">
-<link rel="import" href="signin_view.html">
+ #viewManager :-webkit-any(nux-google-apps, nux-ntp-background,
+ nux-set-as-default) {
+ /* Override cr-view-manager's default styling for view. */
+ bottom: initial;
+ left: initial;
+ margin: auto;
+ position: unset;
+ right: initial;
+ top: initial;
+ }
-<dom-module id="welcome-app">
- <template>
- <style include="cr-hidden-style">
- #viewManager {
- display: flex;
- font-size: 100%;
- margin: 0;
- min-height: 100vh;
- }
-
- #viewManager :-webkit-any(nux-google-apps, nux-ntp-background,
- nux-set-as-default) {
- /* Override cr-view-manager's default styling for view. */
- bottom: initial;
- left: initial;
- margin: auto;
- position: unset;
- right: initial;
- top: initial;
- }
-
- cr-toast {
- min-width: initial;
- }
- </style>
- <cr-view-manager id="viewManager" hidden="[[!modulesInitialized_]]">
- <landing-view id="step-landing" slot="view" class="active"></landing-view>
- </cr-view-manager>
- <cr-toast duration="3000">
- <div>$i18n{defaultBrowserChanged}</div>
- </cr-toast>
- </template>
- <script src="welcome_app.js"></script>
-</dom-module>
+ cr-toast {
+ min-width: initial;
+ }
+</style>
+<cr-view-manager id="viewManager" hidden="[[!modulesInitialized_]]">
+ <landing-view id="step-landing" slot="view" class="active"></landing-view>
+</cr-view-manager>
+<cr-toast duration="3000">
+ <div>$i18n{defaultBrowserChanged}</div>
+</cr-toast>
diff --git a/chromium/chrome/browser/resources/welcome/welcome_app.js b/chromium/chrome/browser/resources/welcome/welcome_app.js
index 9830c921b2a..029129172ef 100644
--- a/chromium/chrome/browser/resources/welcome/welcome_app.js
+++ b/chromium/chrome/browser/resources/welcome/welcome_app.js
@@ -2,6 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js';
+import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js';
+import 'chrome://resources/cr_elements/hidden_style_css.m.js';
+import './google_apps/nux_google_apps.js';
+import './landing_view.js';
+import './ntp_background/nux_ntp_background.js';
+import './set_as_default/nux_set_as_default.js';
+import './signin_view.js';
+import '../strings.m.js';
+
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {navigateTo, navigateToNextStep, NavigationBehavior, Routes} from './navigation_behavior.js';
+import {NuxSetAsDefaultProxyImpl} from './set_as_default/nux_set_as_default_proxy.js';
+import {BookmarkBarManager} from './shared/bookmark_proxy.js';
+import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
+
/**
* The strings contained in the arrays should be valid DOM-element tag names.
* @typedef {{
@@ -31,9 +50,11 @@ const MODULES_NEEDING_INDICATOR =
Polymer({
is: 'welcome-app',
- behaviors: [welcome.NavigationBehavior],
+ _template: html`{__html_template__}`,
+
+ behaviors: [NavigationBehavior],
- /** @private {?welcome.Routes} */
+ /** @private {?Routes} */
currentRoute_: null,
/** @private {NuxOnboardingModules} */
@@ -65,7 +86,7 @@ Polymer({
},
/**
- * @param {welcome.Routes} route
+ * @param {Routes} route
* @param {number} step
* @private
*/
@@ -74,7 +95,7 @@ Polymer({
// If the specified step doesn't exist, that means there are no more
// steps. In that case, replace this page with NTP.
if (!this.$$(`#step-${step}`)) {
- welcome.WelcomeBrowserProxyImpl.getInstance().goToNewTabPage(
+ WelcomeBrowserProxyImpl.getInstance().goToNewTabPage(
/* replace */ true);
} else { // Otherwise, go to the chosen step of that route.
// At this point, views are ready to be shown.
@@ -94,7 +115,7 @@ Polymer({
this.currentRoute_ = route;
},
- /** @param {welcome.Routes} route */
+ /** @param {Routes} route */
initializeModules: function(route) {
// Remove all views except landing.
this.$.viewManager
@@ -102,7 +123,7 @@ Polymer({
.forEach(element => element.remove());
// If it is on landing route, end here.
- if (route == welcome.Routes.LANDING) {
+ if (route == Routes.LANDING) {
return Promise.resolve();
}
@@ -111,7 +132,7 @@ Polymer({
/** @type {!Promise} */
const defaultBrowserPromise =
- welcome.NuxSetAsDefaultProxyImpl.getInstance()
+ NuxSetAsDefaultProxyImpl.getInstance()
.requestDefaultBrowserState()
.then((status) => {
if (status.isDefault || !status.canBeDefault) {
@@ -128,7 +149,7 @@ Polymer({
return Promise
.all([
defaultBrowserPromise,
- welcome.BookmarkBarManager.getInstance().initialized,
+ BookmarkBarManager.getInstance().initialized,
])
.then(([canSetDefault]) => {
modules = modules.filter(module => {
diff --git a/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.html b/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.html
deleted file mode 100644
index 24f332053f2..00000000000
--- a/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<link rel="import" href="chrome://resources/html/cr.html">
-<script src="welcome_browser_proxy.js"></script>
diff --git a/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.js b/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.js
index f549f22e255..bf8146fd786 100644
--- a/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.js
+++ b/chromium/chrome/browser/resources/welcome/welcome_browser_proxy.js
@@ -2,57 +2,52 @@
// 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';
+
/**
* @fileoverview A helper object used by the welcome page to interact with
* the browser.
*/
-cr.define('welcome', function() {
- /** @interface */
- class WelcomeBrowserProxy {
- /** @param {?string} redirectUrl the URL to go to, after signing in. */
- handleActivateSignIn(redirectUrl) {}
+/** @interface */
+export class WelcomeBrowserProxy {
+ /** @param {?string} redirectUrl the URL to go to, after signing in. */
+ handleActivateSignIn(redirectUrl) {}
- handleUserDecline() {}
+ handleUserDecline() {}
- /** @param {boolean=} replace */
- goToNewTabPage(replace) {}
+ /** @param {boolean=} replace */
+ goToNewTabPage(replace) {}
- /** @param {string} url */
- goToURL(url) {}
- }
+ /** @param {string} url */
+ goToURL(url) {}
+}
- /** @implements {welcome.WelcomeBrowserProxy} */
- class WelcomeBrowserProxyImpl {
- /** @override */
- handleActivateSignIn(redirectUrl) {
- chrome.send('handleActivateSignIn', redirectUrl ? [redirectUrl] : []);
- }
-
- /** @override */
- handleUserDecline() {
- chrome.send('handleUserDecline');
- }
+/** @implements {WelcomeBrowserProxy} */
+export class WelcomeBrowserProxyImpl {
+ /** @override */
+ handleActivateSignIn(redirectUrl) {
+ chrome.send('handleActivateSignIn', redirectUrl ? [redirectUrl] : []);
+ }
- /** @override */
- goToNewTabPage(replace) {
- if (replace) {
- window.location.replace('chrome://newtab');
- } else {
- window.location.assign('chrome://newtab');
- }
- }
+ /** @override */
+ handleUserDecline() {
+ chrome.send('handleUserDecline');
+ }
- /** @override */
- goToURL(url) {
- window.location.assign(url);
+ /** @override */
+ goToNewTabPage(replace) {
+ if (replace) {
+ window.location.replace('chrome://newtab');
+ } else {
+ window.location.assign('chrome://newtab');
}
}
- cr.addSingletonGetter(WelcomeBrowserProxyImpl);
+ /** @override */
+ goToURL(url) {
+ window.location.assign(url);
+ }
+}
- return {
- WelcomeBrowserProxy: WelcomeBrowserProxy,
- WelcomeBrowserProxyImpl: WelcomeBrowserProxyImpl,
- };
-});
+addSingletonGetter(WelcomeBrowserProxyImpl);
diff --git a/chromium/chrome/browser/resources/welcome/welcome_resources.grd b/chromium/chrome/browser/resources/welcome/welcome_resources.grd
index cc67d33b906..5a9e022c50c 100644
--- a/chromium/chrome/browser/resources/welcome/welcome_resources.grd
+++ b/chromium/chrome/browser/resources/welcome/welcome_resources.grd
@@ -42,132 +42,79 @@
file="images/background_svgs/yellow_semicircle.svg"
compress="gzip"
type="BINDATA" />
+
+ <!-- Generated Polymer 3 elements -->
+ <include name="IDR_WELCOME_APP_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/welcome_app.js"
+ use_base_dir="false" type="BINDATA" compress="gzip" preprocess="true"/>
+ <include name="IDR_GOOGLE_APPS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/google_apps/nux_google_apps.js"
+ use_base_dir="false" type="BINDATA" compress="gzip" preprocess="true"/>
+ <include name="IDR_SET_AS_DEFAULT_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.js"
+ use_base_dir="false" type="BINDATA" compress="gzip" preprocess="true"/>
+ <include name="IDR_WELCOME_LANDING_VIEW_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/landing_view.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SIGNIN_VIEW_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/signin_view.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_NTP_BACKGROUND_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_STEP_INDICATOR_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/step_indicator.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/onboarding_background.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+
+
+ <!-- Generated style files -->
+ <include name="IDR_WELCOME_SHARED_ANIMATIONS_CSS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/animations_css.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_CHOOSER_SHARED_CSS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/chooser_shared_css.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_NAVI_COLORS_CSS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/navi_colors_css.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_ACTION_LINK_STYLE_CSS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/action_link_style_css.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
+ <include name="IDR_WELCOME_SHARED_SPLASH_PAGES_SHARED_CSS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/welcome/shared/splash_pages_shared_css.js"
+ use_base_dir="false" type="BINDATA" compress="gzip"/>
</includes>
<structures>
- <structure name="IDR_WELCOME_LANDING_VIEW_HTML"
- file="landing_view.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_LANDING_VIEW_JS"
- file="landing_view.js"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_LANDING_VIEW_PROXY_HTML"
- file="landing_view_proxy.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
<structure name="IDR_WELCOME_LANDING_VIEW_PROXY_JS"
file="landing_view_proxy.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_NAVIGATION_BEHAVIOR_HTML"
- file="navigation_behavior.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
<structure name="IDR_WELCOME_NAVIGATION_BEHAVIOR_JS"
file="navigation_behavior.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_SHARED_ACTION_LINK_STYLE_JS"
- file="shared/action_link_style.js"
- compress="gzip"
- type="chrome_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_SHARED_ANIMATIONS_CSS"
- file="shared/animations_css.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_BOOKMARK_PROXY_HTML"
- file="shared/bookmark_proxy.html"
- compress="gzip"
- type="chrome_html" />
<structure name="IDR_WELCOME_SHARED_BOOKMARK_PROXY_JS"
file="shared/bookmark_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_CHOOSER_SHARED_CSS"
- file="shared/chooser_shared_css.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_I18N_SETUP_HTML"
- file="shared/i18n_setup.html"
- compress="gzip"
- type="chrome_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_SHARED_MODULE_METRICS_PROXY_JS"
file="shared/module_metrics_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_NAVI_COLORS_CSS"
- file="shared/navi_colors_css.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_ONBOARDING_BACKGROUND_HTML"
- file="shared/onboarding_background.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS"
- file="shared/onboarding_background.js"
+ <structure name="IDR_WELCOME_SHARED_NUX_TYPES_JS"
+ file="shared/nux_types.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_STEP_INDICATOR_HTML"
- file="shared/step_indicator.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_WELCOME_SHARED_STEP_INDICATOR_JS"
- file="shared/step_indicator.js"
- compress="gzip"
- type="chrome_html" />
- <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_SIGNIN_VIEW_HTML"
- file="signin_view.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_SIGNIN_VIEW_JS"
- file="signin_view.js"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_SIGNIN_VIEW_PROXY_HTML"
- file="signin_view_proxy.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
<structure name="IDR_WELCOME_SIGNIN_VIEW_PROXY_JS"
file="signin_view_proxy.js"
type="chrome_html"
compress="gzip"
preprocess="true"/>
- <structure name="IDR_WELCOME_APP_HTML"
- file="welcome_app.html"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_APP_JS"
- file="welcome_app.js"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_WELCOME_BROWSER_PROXY_HTML"
- file="welcome_browser_proxy.html"
- compress="gzip"
- type="chrome_html"/>
<structure name="IDR_WELCOME_BROWSER_PROXY_JS"
file="welcome_browser_proxy.js"
compress="gzip"
@@ -189,70 +136,26 @@
preprocess="true"/>
<!-- Google apps-->
- <structure name="IDR_GOOGLE_APPS_HTML"
- file="google_apps/nux_google_apps.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_GOOGLE_APPS_JS"
- file="google_apps/nux_google_apps.js"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_GOOGLE_APP_PROXY_HTML"
- file="google_apps/google_app_proxy.html"
- compress="gzip"
- type="chrome_html" />
<structure name="IDR_GOOGLE_APP_PROXY_JS"
file="google_apps/google_app_proxy.js"
compress="gzip"
type="chrome_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_SET_AS_DEFAULT_JS"
- file="set_as_default/nux_set_as_default.js"
- type="chrome_html"
- compress="gzip"
- preprocess="true"/>
- <structure name="IDR_SET_AS_DEFAULT_PROXY_HTML"
- file="set_as_default/nux_set_as_default_proxy.html"
+ <structure name="IDR_GOOGLE_APPS_METRICS_PROXY_JS"
+ file="google_apps/google_apps_metrics_proxy.js"
compress="gzip"
type="chrome_html" />
+
+ <!-- Set as default-->
<structure name="IDR_SET_AS_DEFAULT_PROXY_JS"
file="set_as_default/nux_set_as_default_proxy.js"
compress="gzip"
type="chrome_html" />
- <structure name="IDR_GOOGLE_APPS_METRICS_PROXY_HTML"
- file="google_apps/google_apps_metrics_proxy.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_GOOGLE_APPS_METRICS_PROXY_JS"
- file="google_apps/google_apps_metrics_proxy.js"
- compress="gzip"
- type="chrome_html" />
<!-- NTP background-->
- <structure name="IDR_NTP_BACKGROUND_HTML"
- file="ntp_background/nux_ntp_background.html"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_NTP_BACKGROUND_JS"
- file="ntp_background/nux_ntp_background.js"
- compress="gzip"
- type="chrome_html" />
- <structure name="IDR_NTP_BACKGROUND_PROXY_HTML"
- file="ntp_background/ntp_background_proxy.html"
- compress="gzip"
- type="chrome_html" />
<structure name="IDR_NTP_BACKGROUND_PROXY_JS"
file="ntp_background/ntp_background_proxy.js"
compress="gzip"
type="chrome_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_NTP_BACKGROUND_METRICS_PROXY_JS"
file="ntp_background/ntp_background_metrics_proxy.js"
compress="gzip"